[llvm] b1d58f0 - MCAssembler: Simplify fragment relaxation
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 23 20:13:02 PDT 2025
Author: Fangrui Song
Date: 2025-08-23T20:12:57-07:00
New Revision: b1d58f025e834386acd9a338fcd9ba47d244c67a
URL: https://github.com/llvm/llvm-project/commit/b1d58f025e834386acd9a338fcd9ba47d244c67a
DIFF: https://github.com/llvm/llvm-project/commit/b1d58f025e834386acd9a338fcd9ba47d244c67a.diff
LOG: MCAssembler: Simplify fragment relaxation
* FT_Data: skip relaxFragment
* Others: Call relaxFragment, which computes the old size, calls the
relevant relaxXXX function, then compares the size.
Added:
Modified:
llvm/include/llvm/MC/MCAsmBackend.h
llvm/include/llvm/MC/MCAssembler.h
llvm/lib/MC/MCAssembler.cpp
llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 311d9ca8321c7..1625355323692 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -166,12 +166,8 @@ class LLVM_ABI MCAsmBackend {
// Return false to use default handling. Otherwise, set `Size` to the number
// of padding bytes.
virtual bool relaxAlign(MCFragment &F, unsigned &Size) { return false; }
- virtual bool relaxDwarfLineAddr(MCFragment &, bool &WasRelaxed) const {
- return false;
- }
- virtual bool relaxDwarfCFA(MCFragment &, bool &WasRelaxed) const {
- return false;
- }
+ virtual bool relaxDwarfLineAddr(MCFragment &) const { return false; }
+ virtual bool relaxDwarfCFA(MCFragment &) const { return false; }
// Defined by linker relaxation targets to possibly emit LEB128 relocations
// and set Value at the relocated location.
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index afd38d2e6d106..1316d8669239d 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -112,15 +112,11 @@ class MCAssembler {
/// Perform relaxation on a single fragment.
bool relaxFragment(MCFragment &F);
- bool relaxInstruction(MCFragment &F);
- bool relaxLEB(MCFragment &F);
- bool relaxBoundaryAlign(MCBoundaryAlignFragment &BF);
- bool relaxDwarfLineAddr(MCFragment &F);
- bool relaxDwarfCallFrameFragment(MCFragment &F);
- bool relaxCVInlineLineTable(MCCVInlineLineTableFragment &DF);
- bool relaxCVDefRange(MCCVDefRangeFragment &DF);
- bool relaxFill(MCFillFragment &F);
- bool relaxOrg(MCOrgFragment &F);
+ void relaxInstruction(MCFragment &F);
+ void relaxLEB(MCFragment &F);
+ void relaxBoundaryAlign(MCBoundaryAlignFragment &BF);
+ void relaxDwarfLineAddr(MCFragment &F);
+ void relaxDwarfCallFrameFragment(MCFragment &F);
public:
/// Construct a new assembler instance.
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 0012590daf5a2..29a9fadbe2433 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -203,7 +203,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCFragment &F) const {
case MCFragment::FT_CVDefRange:
return F.getSize();
case MCFragment::FT_Fill: {
- auto &FF = cast<MCFillFragment>(F);
+ auto &FF = static_cast<const MCFillFragment &>(F);
int64_t NumValues = 0;
if (!FF.getNumValues().evaluateKnownAbsolute(NumValues, *this)) {
recordError(FF.getLoc(), "expected assembly-time absolute expression");
@@ -748,7 +748,7 @@ bool MCAssembler::fixupNeedsRelaxation(const MCFragment &F,
Resolved);
}
-bool MCAssembler::relaxInstruction(MCFragment &F) {
+void MCAssembler::relaxInstruction(MCFragment &F) {
assert(getEmitterPtr() &&
"Expected CodeEmitter defined for relaxInstruction");
// If this inst doesn't ever need relaxation, ignore it. This occurs when we
@@ -756,14 +756,14 @@ bool MCAssembler::relaxInstruction(MCFragment &F) {
// previous instruction to one that doesn't need relaxation.
if (!getBackend().mayNeedRelaxation(F.getOpcode(), F.getOperands(),
*F.getSubtargetInfo()))
- return false;
+ return;
bool DoRelax = false;
for (const MCFixup &Fixup : F.getVarFixups())
if ((DoRelax = fixupNeedsRelaxation(F, Fixup)))
break;
if (!DoRelax)
- return false;
+ return;
++stats::RelaxedInstructions;
@@ -779,12 +779,10 @@ bool MCAssembler::relaxInstruction(MCFragment &F) {
getEmitter().encodeInstruction(Relaxed, Data, Fixups, *F.getSubtargetInfo());
F.setVarContents(Data);
F.setVarFixups(Fixups);
- return true;
}
-bool MCAssembler::relaxLEB(MCFragment &F) {
- const unsigned OldSize = F.getVarSize();
- unsigned PadTo = OldSize;
+void MCAssembler::relaxLEB(MCFragment &F) {
+ unsigned PadTo = F.getVarSize();
int64_t Value;
F.clearVarFixups();
// Use evaluateKnownAbsolute for Mach-O as a hack: .subsections_via_symbols
@@ -818,7 +816,6 @@ bool MCAssembler::relaxLEB(MCFragment &F) {
else
Size = encodeULEB128(Value, Data, PadTo);
F.setVarContents({reinterpret_cast<char *>(Data), Size});
- return OldSize != Size;
}
/// Check if the branch crosses the boundary.
@@ -858,11 +855,11 @@ static bool needPadding(uint64_t StartAddr, uint64_t Size,
isAgainstBoundary(StartAddr, Size, BoundaryAlignment);
}
-bool MCAssembler::relaxBoundaryAlign(MCBoundaryAlignFragment &BF) {
+void MCAssembler::relaxBoundaryAlign(MCBoundaryAlignFragment &BF) {
// BoundaryAlignFragment that doesn't need to align any fragment should not be
// relaxed.
if (!BF.getLastFragment())
- return false;
+ return;
uint64_t AlignedOffset = getFragmentOffset(BF);
uint64_t AlignedSize = 0;
@@ -877,18 +874,15 @@ bool MCAssembler::relaxBoundaryAlign(MCBoundaryAlignFragment &BF) {
? offsetToAlignment(AlignedOffset, BoundaryAlignment)
: 0U;
if (NewSize == BF.getSize())
- return false;
+ return;
BF.setSize(NewSize);
- return true;
}
-bool MCAssembler::relaxDwarfLineAddr(MCFragment &F) {
- bool WasRelaxed;
- if (getBackend().relaxDwarfLineAddr(F, WasRelaxed))
- return WasRelaxed;
+void MCAssembler::relaxDwarfLineAddr(MCFragment &F) {
+ if (getBackend().relaxDwarfLineAddr(F))
+ return;
MCContext &Context = getContext();
- auto OldSize = F.getVarSize();
int64_t AddrDelta;
bool Abs = F.getDwarfAddrDelta().evaluateKnownAbsolute(AddrDelta, *this);
assert(Abs && "We created a line delta with an invalid expression");
@@ -898,13 +892,11 @@ bool MCAssembler::relaxDwarfLineAddr(MCFragment &F) {
F.getDwarfLineDelta(), AddrDelta, Data);
F.setVarContents(Data);
F.clearVarFixups();
- return OldSize != Data.size();
}
-bool MCAssembler::relaxDwarfCallFrameFragment(MCFragment &F) {
- bool WasRelaxed;
- if (getBackend().relaxDwarfCFA(F, WasRelaxed))
- return WasRelaxed;
+void MCAssembler::relaxDwarfCallFrameFragment(MCFragment &F) {
+ if (getBackend().relaxDwarfCFA(F))
+ return;
MCContext &Context = getContext();
int64_t Value;
@@ -913,69 +905,60 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCFragment &F) {
reportError(F.getDwarfAddrDelta().getLoc(),
"invalid CFI advance_loc expression");
F.setDwarfAddrDelta(MCConstantExpr::create(0, Context));
- return false;
+ return;
}
- auto OldSize = F.getVarContents().size();
SmallVector<char, 8> Data;
MCDwarfFrameEmitter::encodeAdvanceLoc(Context, Value, Data);
F.setVarContents(Data);
F.clearVarFixups();
- return OldSize != Data.size();
-}
-
-bool MCAssembler::relaxCVInlineLineTable(MCCVInlineLineTableFragment &F) {
- unsigned OldSize = F.getVarContents().size();
- getContext().getCVContext().encodeInlineLineTable(*this, F);
- return OldSize != F.getVarContents().size();
-}
-
-bool MCAssembler::relaxCVDefRange(MCCVDefRangeFragment &F) {
- unsigned OldSize = F.getVarContents().size();
- getContext().getCVContext().encodeDefRange(*this, F);
- return OldSize != F.getVarContents().size();
-}
-
-bool MCAssembler::relaxFill(MCFillFragment &F) {
- uint64_t Size = computeFragmentSize(F);
- if (F.getSize() == Size)
- return false;
- F.setSize(Size);
- return true;
-}
-
-bool MCAssembler::relaxOrg(MCOrgFragment &F) {
- uint64_t Size = computeFragmentSize(F);
- if (F.getSize() == Size)
- return false;
- F.setSize(Size);
- return true;
}
bool MCAssembler::relaxFragment(MCFragment &F) {
- switch(F.getKind()) {
+ size_t Size = computeFragmentSize(F);
+ switch (F.getKind()) {
default:
return false;
case MCFragment::FT_Relaxable:
assert(!getRelaxAll() && "Did not expect a FT_Relaxable in RelaxAll mode");
- return relaxInstruction(F);
+ relaxInstruction(F);
+ break;
case MCFragment::FT_LEB:
- return relaxLEB(F);
+ relaxLEB(F);
+ break;
case MCFragment::FT_Dwarf:
- return relaxDwarfLineAddr(F);
+ relaxDwarfLineAddr(F);
+ break;
case MCFragment::FT_DwarfFrame:
- return relaxDwarfCallFrameFragment(F);
+ relaxDwarfCallFrameFragment(F);
+ break;
case MCFragment::FT_BoundaryAlign:
- return relaxBoundaryAlign(cast<MCBoundaryAlignFragment>(F));
+ relaxBoundaryAlign(static_cast<MCBoundaryAlignFragment &>(F));
+ break;
case MCFragment::FT_CVInlineLines:
- return relaxCVInlineLineTable(cast<MCCVInlineLineTableFragment>(F));
+ getContext().getCVContext().encodeInlineLineTable(
+ *this, static_cast<MCCVInlineLineTableFragment &>(F));
+ break;
case MCFragment::FT_CVDefRange:
- return relaxCVDefRange(cast<MCCVDefRangeFragment>(F));
- case MCFragment::FT_Fill:
- return relaxFill(cast<MCFillFragment>(F));
- case MCFragment::FT_Org:
- return relaxOrg(static_cast<MCOrgFragment &>(F));
+ getContext().getCVContext().encodeDefRange(
+ *this, static_cast<MCCVDefRangeFragment &>(F));
+ break;
+ case MCFragment::FT_Fill: {
+ auto &FF = static_cast<MCFillFragment &>(F);
+ if (FF.getSize() == Size)
+ return false;
+ FF.setSize(Size);
+ return true;
+ }
+ case MCFragment::FT_Org: {
+ auto &FF = static_cast<MCOrgFragment &>(F);
+ if (FF.getSize() == Size)
+ return false;
+ FF.setSize(Size);
+ return true;
+ }
}
+ return computeFragmentSize(F) != Size;
}
void MCAssembler::layoutSection(MCSection &Sec) {
@@ -1024,7 +1007,7 @@ unsigned MCAssembler::relaxOnce(unsigned FirstStable) {
for (;;) {
bool Changed = false;
for (MCFragment &F : Sec)
- if (relaxFragment(F))
+ if (F.getKind() != MCFragment::FT_Data && relaxFragment(F))
Changed = true;
if (!Changed)
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
index 3b38ac95dcafa..0696813040654 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.cpp
@@ -259,14 +259,10 @@ std::pair<bool, bool> LoongArchAsmBackend::relaxLEB128(MCFragment &F,
return std::make_pair(true, true);
}
-bool LoongArchAsmBackend::relaxDwarfLineAddr(MCFragment &F,
- bool &WasRelaxed) const {
+bool LoongArchAsmBackend::relaxDwarfLineAddr(MCFragment &F) const {
MCContext &C = getContext();
-
int64_t LineDelta = F.getDwarfLineDelta();
const MCExpr &AddrDelta = F.getDwarfAddrDelta();
- size_t OldSize = F.getVarSize();
-
int64_t Value;
if (AddrDelta.evaluateAsAbsolute(Value, *Asm))
return false;
@@ -312,15 +308,12 @@ bool LoongArchAsmBackend::relaxDwarfLineAddr(MCFragment &F,
F.setVarContents(Data);
F.setVarFixups({MCFixup::create(Offset, &AddrDelta,
MCFixup::getDataKindForSize(PCBytes))});
- WasRelaxed = OldSize != Data.size();
return true;
}
-bool LoongArchAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const {
+bool LoongArchAsmBackend::relaxDwarfCFA(MCFragment &F) const {
const MCExpr &AddrDelta = F.getDwarfAddrDelta();
SmallVector<MCFixup, 2> Fixups;
- size_t OldSize = F.getVarContents().size();
-
int64_t Value;
if (AddrDelta.evaluateAsAbsolute(Value, *Asm))
return false;
@@ -333,7 +326,6 @@ bool LoongArchAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const {
if (Value == 0) {
F.clearVarContents();
F.clearVarFixups();
- WasRelaxed = OldSize != 0;
return true;
}
@@ -367,8 +359,6 @@ bool LoongArchAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const {
}
F.setVarContents(Data);
F.setVarFixups(Fixups);
-
- WasRelaxed = OldSize != Data.size();
return true;
}
diff --git a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
index f79d3aa48c54c..8236e300a6ab2 100644
--- a/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
+++ b/llvm/lib/Target/LoongArch/MCTargetDesc/LoongArchAsmBackend.h
@@ -49,8 +49,8 @@ class LoongArchAsmBackend : public MCAsmBackend {
MCFixupKindInfo getFixupKindInfo(MCFixupKind Kind) const override;
bool relaxAlign(MCFragment &F, unsigned &Size) override;
- bool relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const override;
- bool relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const override;
+ bool relaxDwarfLineAddr(MCFragment &) const override;
+ bool relaxDwarfCFA(MCFragment &) const override;
std::pair<bool, bool> relaxLEB128(MCFragment &F,
int64_t &Value) const override;
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
index c69c8bfe00679..41a9c92cf99c3 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
@@ -340,12 +340,9 @@ bool RISCVAsmBackend::relaxAlign(MCFragment &F, unsigned &Size) {
return true;
}
-bool RISCVAsmBackend::relaxDwarfLineAddr(MCFragment &F,
- bool &WasRelaxed) const {
+bool RISCVAsmBackend::relaxDwarfLineAddr(MCFragment &F) const {
int64_t LineDelta = F.getDwarfLineDelta();
const MCExpr &AddrDelta = F.getDwarfAddrDelta();
- size_t OldSize = F.getVarSize();
-
int64_t Value;
// If the label
diff erence can be resolved, use the default handling, which
// utilizes a shorter special opcode.
@@ -391,15 +388,12 @@ bool RISCVAsmBackend::relaxDwarfLineAddr(MCFragment &F,
F.setVarContents(Data);
F.setVarFixups({MCFixup::create(Offset, &AddrDelta,
MCFixup::getDataKindForSize(PCBytes))});
- WasRelaxed = OldSize != Data.size();
return true;
}
-bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const {
+bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F) const {
const MCExpr &AddrDelta = F.getDwarfAddrDelta();
SmallVector<MCFixup, 2> Fixups;
- size_t OldSize = F.getVarSize();
-
int64_t Value;
if (AddrDelta.evaluateAsAbsolute(Value, *Asm))
return false;
@@ -412,7 +406,6 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const {
if (Value == 0) {
F.clearVarContents();
F.clearVarFixups();
- WasRelaxed = OldSize != 0;
return true;
}
@@ -445,8 +438,6 @@ bool RISCVAsmBackend::relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const {
}
F.setVarContents(Data);
F.setVarFixups(Fixups);
-
- WasRelaxed = OldSize != Data.size();
return true;
}
diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
index 3a5214a5f350f..5152d054cb177 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
@@ -65,8 +65,8 @@ class RISCVAsmBackend : public MCAsmBackend {
const MCSubtargetInfo &STI) const override;
bool relaxAlign(MCFragment &F, unsigned &Size) override;
- bool relaxDwarfLineAddr(MCFragment &F, bool &WasRelaxed) const override;
- bool relaxDwarfCFA(MCFragment &F, bool &WasRelaxed) const override;
+ bool relaxDwarfLineAddr(MCFragment &) const override;
+ bool relaxDwarfCFA(MCFragment &) const override;
std::pair<bool, bool> relaxLEB128(MCFragment &LF,
int64_t &Value) const override;
More information about the llvm-commits
mailing list