diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2024-08-06 13:37:26 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2024-10-23 18:26:53 +0000 |
| commit | 52418fc2be8efa5172b90a3a9e617017173612c4 (patch) | |
| tree | b571eeb754eccf2c639c79a81de6c6225a5cf384 /contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp | |
| parent | ff6c8447844b0f48bf507b2af4a0b8870e34e09e (diff) | |
| parent | 9b9503334fa856ed4ed6823d35b6f52546296f77 (diff) | |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp | 77 |
1 files changed, 37 insertions, 40 deletions
diff --git a/contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp b/contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp index ceeb7af0fecc..c3da4bb5cc36 100644 --- a/contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp +++ b/contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp @@ -432,6 +432,28 @@ void MCAssembler::layoutBundle(MCFragment *Prev, MCFragment *F) const { DF->Offset = EF->Offset; } +void MCAssembler::ensureValid(MCSection &Sec) const { + if (Sec.hasLayout()) + return; + Sec.setHasLayout(true); + MCFragment *Prev = nullptr; + uint64_t Offset = 0; + for (MCFragment &F : Sec) { + F.Offset = Offset; + if (isBundlingEnabled() && F.hasInstructions()) { + layoutBundle(Prev, &F); + Offset = F.Offset; + } + Offset += computeFragmentSize(F); + Prev = &F; + } +} + +uint64_t MCAssembler::getFragmentOffset(const MCFragment &F) const { + ensureValid(*F.getParent()); + return F.Offset; +} + // Simple getSymbolOffset helper for the non-variable case. static bool getLabelOffset(const MCAssembler &Asm, const MCSymbol &S, bool ReportError, uint64_t &Val) { @@ -916,20 +938,22 @@ void MCAssembler::layout() { // Layout until everything fits. this->HasLayout = true; - for (MCSection &Sec : *this) - layoutSection(Sec); while (layoutOnce()) { + if (getContext().hadError()) + return; + // 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. + for (MCSection &Sec : *this) + Sec.setHasLayout(false); } DEBUG_WITH_TYPE("mc-dump", { errs() << "assembler backend - post-relaxation\n--\n"; dump(); }); - // Some targets might want to adjust fragment offsets. If so, perform another - // layout loop. - if (getBackend().finishLayout(*this)) - for (MCSection &Sec : *this) - layoutSection(Sec); + // Finalize the layout, including fragment lowering. + getBackend().finishLayout(*this); DEBUG_WITH_TYPE("mc-dump", { errs() << "assembler backend - final-layout\n--\n"; @@ -1282,42 +1306,15 @@ bool MCAssembler::relaxFragment(MCFragment &F) { } } -void MCAssembler::layoutSection(MCSection &Sec) { - MCFragment *Prev = nullptr; - uint64_t Offset = 0; - for (MCFragment &F : Sec) { - F.Offset = Offset; - if (LLVM_UNLIKELY(isBundlingEnabled())) { - if (F.hasInstructions()) { - layoutBundle(Prev, &F); - Offset = F.Offset; - } - Prev = &F; - } - Offset += computeFragmentSize(F); - } -} - bool MCAssembler::layoutOnce() { ++stats::RelaxationSteps; - // 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. - bool ChangedAny = false; - for (MCSection &Sec : *this) { - for (;;) { - bool Changed = false; - for (MCFragment &F : Sec) - if (relaxFragment(F)) - Changed = true; - ChangedAny |= Changed; - if (!Changed) - break; - layoutSection(Sec); - } - } - return ChangedAny; + bool Changed = false; + for (MCSection &Sec : *this) + for (MCFragment &Frag : Sec) + if (relaxFragment(Frag)) + Changed = true; + return Changed; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
