aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/MC/MCExpr.cpp
diff options
context:
space:
mode:
authorFangrui Song <i@maskray.me>2024-06-11 09:18:31 -0700
committerGitHub <noreply@github.com>2024-06-11 09:18:31 -0700
commitde19f7b6d46f1c38e10e604154f0fdaaffde9ebd (patch)
treec12a54c936c1a823b3589b30e1974b4bb07ef759 /llvm/lib/MC/MCExpr.cpp
parent4cf607fa15fd9ccd79115095a1eb02e0cd83e1a9 (diff)
downloadllvm-de19f7b6d46f1c38e10e604154f0fdaaffde9ebd.zip
llvm-de19f7b6d46f1c38e10e604154f0fdaaffde9ebd.tar.gz
llvm-de19f7b6d46f1c38e10e604154f0fdaaffde9ebd.tar.bz2
[MC] Replace fragment ilist with singly-linked lists
Fragments are allocated with `operator new` and stored in an ilist with Prev/Next/Parent pointers. A more efficient representation would be an array of fragments without the overhead of Prev/Next pointers. As the first step, replace ilist with singly-linked lists. * `getPrevNode` uses have been eliminated by previous changes. * The last use of the `Prev` pointer remains: for each subsection, there is an insertion point and the current insertion point is stored at `CurInsertionPoint`. * `HexagonAsmBackend::finishLayout` needs a backward iterator. Save all fragments within `Frags`. Hexagon programs are usually small, and the performance does not matter that much. To eliminate `Prev`, change the subsection representation to singly-linked lists for subsections and a pointer to the active singly-linked list. The fragments from all subsections will be chained together at layout time. Since fragment lists are disconnected before layout time, we can remove `MCFragment::SubsectionNumber` (https://reviews.llvm.org/D69411). The current implementation of `AttemptToFoldSymbolOffsetDifference` requires future improvement for robustness. Pull Request: https://github.com/llvm/llvm-project/pull/95077
Diffstat (limited to 'llvm/lib/MC/MCExpr.cpp')
-rw-r--r--llvm/lib/MC/MCExpr.cpp31
1 files changed, 12 insertions, 19 deletions
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index b70ac86..2eecdb8 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -661,25 +661,16 @@ static void AttemptToFoldSymbolOffsetDifference(
// this is important when the Subtarget is changed and a new MCDataFragment
// is created in the case of foo: instr; .arch_extension ext; instr .if . -
// foo.
- if (SA.isVariable() || SB.isVariable() ||
- FA->getSubsectionNumber() != FB->getSubsectionNumber())
+ if (SA.isVariable() || SB.isVariable())
return;
// Try to find a constant displacement from FA to FB, add the displacement
// between the offset in FA of SA and the offset in FB of SB.
bool Reverse = false;
- if (FA == FB) {
+ if (FA == FB)
Reverse = SA.getOffset() < SB.getOffset();
- } else if (!isa<MCDummyFragment>(FA)) {
- // Testing FA < FB is slow. Use setLayoutOrder to speed up computation.
- // The formal layout order will be finalized in MCAssembler::layout.
- if (FA->getLayoutOrder() == 0 || FB->getLayoutOrder()== 0) {
- unsigned LayoutOrder = 0;
- for (MCFragment &F : *FA->getParent())
- F.setLayoutOrder(++LayoutOrder);
- }
+ else if (!isa<MCDummyFragment>(FA))
Reverse = FA->getLayoutOrder() < FB->getLayoutOrder();
- }
uint64_t SAOffset = SA.getOffset(), SBOffset = SB.getOffset();
int64_t Displacement = SA.getOffset() - SB.getOffset();
@@ -695,7 +686,7 @@ static void AttemptToFoldSymbolOffsetDifference(
// instruction, the difference cannot be resolved as it may be changed by
// the linker.
bool BBeforeRelax = false, AAfterRelax = false;
- for (auto FI = FB->getIterator(), FE = SecA.end(); FI != FE; ++FI) {
+ for (auto FI = FB; FI; FI = FI->getNext()) {
auto DF = dyn_cast<MCDataFragment>(FI);
if (DF && DF->isLinkerRelaxable()) {
if (&*FI != FB || SBOffset != DF->getContents().size())
@@ -726,12 +717,14 @@ static void AttemptToFoldSymbolOffsetDifference(
return;
}
}
- // If the previous loop does not find FA, FA must be a dummy fragment not in
- // the fragment list (which means SA is a pending label (see
- // flushPendingLabels)). In either case, we can resolve the difference.
- assert(Found || isa<MCDummyFragment>(FA));
- Addend += Reverse ? -Displacement : Displacement;
- FinalizeFolding();
+ // If FA and FB belong to the same subsection, either the previous loop
+ // found FA, or FA is a dummy fragment not in the fragment list (which means
+ // SA is a pending label (see flushPendingLabels)) or FA and FB belong to
+ // different subsections. In either case, we can resolve the difference.
+ if (Found || isa<MCDummyFragment>(FA)) {
+ Addend += Reverse ? -Displacement : Displacement;
+ FinalizeFolding();
+ }
}
}