[go: nahoru, domu]

Skip to content

Commit

Permalink
[MC] Start merging MCAsmLayout into MCAssembler
Browse files Browse the repository at this point in the history
Follow-up to 10c894c.

MCAsmLayout, introduced by ac8a954
(2010), provides APIs to compute fragment/symbol/section offsets.
The separate class is cumbersome and passing it around has overhead.
Let's remove it as the underlying implementation is tightly coupled with
MCAsmLayout anyway.

Some forwarders are added to ease migration.
  • Loading branch information
MaskRay committed Jun 30, 2024
1 parent 3cf762b commit 67957a4
Show file tree
Hide file tree
Showing 11 changed files with 203 additions and 208 deletions.
9 changes: 0 additions & 9 deletions llvm/include/llvm/MC/MCAsmLayout.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,12 @@ class MCAsmLayout {
/// List of sections in layout order.
llvm::SmallVector<MCSection *, 16> SectionOrder;

/// Compute the layout for the section if necessary.
void ensureValid(const MCFragment *F) const;

public:
MCAsmLayout(MCAssembler &Assembler);

/// Get the assembler object this is a layout for.
MCAssembler &getAssembler() const { return Assembler; }

void layoutBundle(MCFragment *Prev, MCFragment *F);

/// \name Section Access (in layout order)
/// @{
Expand Down Expand Up @@ -70,11 +66,6 @@ class MCAsmLayout {
/// file. This may include additional padding, or be 0 for virtual sections.
uint64_t getSectionFileSize(const MCSection *Sec) const;

/// Get the offset of the given symbol, as computed in the current
/// layout.
/// \return True on success.
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const;

/// Variant that reports a fatal error if the offset is not computable.
uint64_t getSymbolOffset(const MCSymbol &S) const;

Expand Down
71 changes: 42 additions & 29 deletions llvm/include/llvm/MC/MCAssembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ class MCAssembler {
std::unique_ptr<MCCodeEmitter> Emitter;
std::unique_ptr<MCObjectWriter> Writer;

MCAsmLayout *Layout = nullptr;
bool RelaxAll = false;
bool SubsectionsViaSymbols = false;
bool IncrementalLinkerCompatible = false;
Expand Down Expand Up @@ -171,7 +172,6 @@ class MCAssembler {
/// Evaluate a fixup to a relocatable expression and the value which should be
/// placed into the fixup.
///
/// \param Layout The layout to use for evaluation.
/// \param Fixup The fixup to evaluate.
/// \param DF The fragment the fixup is inside.
/// \param Target [out] On return, the relocatable expression the fixup
Expand All @@ -183,45 +183,38 @@ class MCAssembler {
/// \return Whether the fixup value was fully resolved. This is true if the
/// \p Value result is fixed, otherwise the value may change due to
/// relocation.
bool evaluateFixup(const MCAsmLayout &Layout, const MCFixup &Fixup,
const MCFragment *DF, MCValue &Target,
const MCSubtargetInfo *STI, uint64_t &Value,
bool &WasForced) const;
bool evaluateFixup(const MCFixup &Fixup, const MCFragment *DF,
MCValue &Target, const MCSubtargetInfo *STI,
uint64_t &Value, bool &WasForced) const;

/// Check whether a fixup can be satisfied, or whether it needs to be relaxed
/// (increased in size, in order to hold its value correctly).
bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF,
const MCAsmLayout &Layout) const;
bool fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF) const;

/// Check whether the given fragment needs relaxation.
bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF,
const MCAsmLayout &Layout) const;
bool fragmentNeedsRelaxation(const MCRelaxableFragment *IF) const;

/// Perform one layout iteration and return true if any offsets
/// were adjusted.
bool layoutOnce(MCAsmLayout &Layout);
bool layoutOnce();

/// Perform relaxation on a single fragment - returns true if the fragment
/// changes as a result of relaxation.
bool relaxFragment(MCAsmLayout &Layout, MCFragment &F);
bool relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &IF);
bool relaxLEB(MCAsmLayout &Layout, MCLEBFragment &IF);
bool relaxBoundaryAlign(MCAsmLayout &Layout, MCBoundaryAlignFragment &BF);
bool relaxDwarfLineAddr(MCAsmLayout &Layout, MCDwarfLineAddrFragment &DF);
bool relaxDwarfCallFrameFragment(MCAsmLayout &Layout,
MCDwarfCallFrameFragment &DF);
bool relaxCVInlineLineTable(MCAsmLayout &Layout,
MCCVInlineLineTableFragment &DF);
bool relaxCVDefRange(MCAsmLayout &Layout, MCCVDefRangeFragment &DF);
bool relaxPseudoProbeAddr(MCAsmLayout &Layout, MCPseudoProbeAddrFragment &DF);
bool relaxFragment(MCFragment &F);
bool relaxInstruction(MCRelaxableFragment &IF);
bool relaxLEB(MCLEBFragment &IF);
bool relaxBoundaryAlign(MCBoundaryAlignFragment &BF);
bool relaxDwarfLineAddr(MCDwarfLineAddrFragment &DF);
bool relaxDwarfCallFrameFragment(MCDwarfCallFrameFragment &DF);
bool relaxCVInlineLineTable(MCCVInlineLineTableFragment &DF);
bool relaxCVDefRange(MCCVDefRangeFragment &DF);
bool relaxPseudoProbeAddr(MCPseudoProbeAddrFragment &DF);

/// finishLayout - Finalize a layout, including fragment lowering.
void finishLayout(MCAsmLayout &Layout);

std::tuple<MCValue, uint64_t, bool> handleFixup(const MCAsmLayout &Layout,
MCFragment &F,
const MCFixup &Fixup,
const MCSubtargetInfo *STI);
std::tuple<MCValue, uint64_t, bool>
handleFixup(MCFragment &F, const MCFixup &Fixup, const MCSubtargetInfo *STI);

public:
struct Symver {
Expand All @@ -246,10 +239,28 @@ class MCAssembler {
MCAssembler &operator=(const MCAssembler &) = delete;
~MCAssembler();

/// Compute the effective fragment size assuming it is laid out at the given
/// \p SectionAddress and \p FragmentOffset.
uint64_t computeFragmentSize(const MCAsmLayout &Layout,
const MCFragment &F) const;
/// Compute the effective fragment size.
uint64_t computeFragmentSize(const MCFragment &F) const;

void layoutBundle(MCFragment *Prev, MCFragment *F) const;
void ensureValid(MCSection &Sec) const;

// Get the offset of the given fragment inside its containing section.
uint64_t getFragmentOffset(const MCFragment &F) const;

uint64_t getSectionAddressSize(const MCSection &Sec) const;
uint64_t getSectionFileSize(const MCSection &Sec) const;

// Get the offset of the given symbol, as computed in the current
// layout.
// \return True on success.
bool getSymbolOffset(const MCSymbol &S, uint64_t &Val) const;

// Variant that reports a fatal error if the offset is not computable.
uint64_t getSymbolOffset(const MCSymbol &S) const;

// If this symbol is equivalent to A + Constant, return A.
const MCSymbol *getBaseSymbol(const MCSymbol &Symbol) const;

/// Check whether a particular symbol is visible to the linker and is required
/// in the symbol table, or whether it can be discarded by the assembler. This
Expand Down Expand Up @@ -349,6 +360,8 @@ class MCAssembler {
IncrementalLinkerCompatible = Value;
}

MCAsmLayout *getLayout() const { return Layout; }
bool hasLayout() const { return Layout; }
bool getRelaxAll() const { return RelaxAll; }
void setRelaxAll(bool Value) { RelaxAll = Value; }

Expand Down
8 changes: 2 additions & 6 deletions llvm/include/llvm/MC/MCExpr.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ class MCExpr {
}

bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const MCFixup *Fixup,
const SectionAddrMap *Addrs, bool InSet) const;

Expand Down Expand Up @@ -96,11 +95,8 @@ class MCExpr {
/// Try to evaluate the expression to an absolute value.
///
/// \param Res - The absolute value, if evaluation succeeds.
/// \param Layout - The assembler layout object to use for evaluating symbol
/// values. If not given, then only non-symbolic expressions will be
/// evaluated.
/// \return - True on success.
bool evaluateAsAbsolute(int64_t &Res, const MCAsmLayout &Layout,
bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm,
const SectionAddrMap &Addrs) const;
bool evaluateAsAbsolute(int64_t &Res) const;
bool evaluateAsAbsolute(int64_t &Res, const MCAssembler &Asm) const;
Expand All @@ -124,7 +120,7 @@ class MCExpr {
///
/// This is a more aggressive variant of evaluateAsRelocatable. The intended
/// use is for when relocations are not available, like the .size directive.
bool evaluateAsValue(MCValue &Res, const MCAsmLayout &Layout) const;
bool evaluateAsValue(MCValue &Res, const MCAssembler &Asm) const;

/// Find the "associated section" for this expression, which is
/// currently defined as the absolute section for constants, or
Expand Down
11 changes: 5 additions & 6 deletions llvm/lib/MC/ELFObjectWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ struct ELFWriter {
DwoOnly,
} Mode;

static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
static uint64_t symbolValue(const MCSymbol &Sym, const MCAssembler &Asm);
static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
bool Used, bool Renamed);

Expand Down Expand Up @@ -454,16 +454,15 @@ void ELFWriter::writeHeader(const MCAssembler &Asm) {
W.write<uint16_t>(StringTableIndex);
}

uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
const MCAsmLayout &Layout) {
uint64_t ELFWriter::symbolValue(const MCSymbol &Sym, const MCAssembler &Asm) {
if (Sym.isCommon())
return Sym.getCommonAlignment()->value();

uint64_t Res;
if (!Layout.getSymbolOffset(Sym, Res))
if (!Asm.getSymbolOffset(Sym, Res))
return 0;

if (Layout.getAssembler().isThumbFunc(&Sym))
if (Asm.isThumbFunc(&Sym))
Res |= 1;

return Res;
Expand Down Expand Up @@ -542,7 +541,7 @@ void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
uint8_t Visibility = Symbol.getVisibility();
uint8_t Other = Symbol.getOther() | Visibility;

uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
uint64_t Value = symbolValue(*MSD.Symbol, Layout.getAssembler());
uint64_t Size = 0;

const MCExpr *ESize = MSD.Symbol->getSize();
Expand Down
Loading

0 comments on commit 67957a4

Please sign in to comment.