Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 49 additions & 72 deletions llvm/include/llvm/MC/MCFragment.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ class MCSection;
class MCSubtargetInfo;
class MCSymbol;

// Represents a contiguous segment of code or data within a section. Its size is
// determined by MCAssembler::layout. All subclasses (except
// MCRelaxableFragment, which stores a MCInst) must have trivial destructors.
class MCFragment {
friend class MCAssembler;
friend class MCObjectStreamer;
Expand Down Expand Up @@ -86,12 +89,6 @@ class MCFragment {
MCFragment(const MCFragment &) = delete;
MCFragment &operator=(const MCFragment &) = delete;

/// Destroys the current fragment.
///
/// This must be used instead of delete as MCFragment is non-virtual.
/// This method will dispatch to the appropriate subclass.
LLVM_ABI void destroy();

MCFragment *getNext() const { return Next; }

FragmentType getKind() const { return Kind; }
Expand All @@ -113,10 +110,7 @@ class MCFragment {

/// Interface implemented by fragments that contain encoded instructions and/or
/// data.
///
class MCEncodedFragment : public MCFragment {
uint8_t BundlePadding = 0;

protected:
MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions)
: MCFragment(FType, HasInstructions) {}
Expand All @@ -125,6 +119,13 @@ class MCEncodedFragment : public MCFragment {
/// It must be non-null for instructions.
const MCSubtargetInfo *STI = nullptr;

private:
uint32_t ContentStart = 0;
uint32_t ContentSize = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more comment: This limits the size of actual section contents to 2**32-1, I think we supported larger sections before? Maybe we should use size_t here. Depending on usage, we might also want to store start/end instead of start/size to simplify checks w.r.t. ContentStorage.size().

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content size is limited to 2^32-1, which is somewhat restrictive but necessary to keep the MCDataFragment class size smaller. This is a makeshift. In the future we should try allocating the content as the trailing object of MCDataFragment and adjusting allocFragment. GNU Assembler uses gnulib obstack to allocate content as part of its fragment structure.

(BTW, BundlePadding (due to deprecated NaCl) is at offset 56. If we remove NaCl, we can likely make MCDataFragment smaller.)

uint32_t FixupStart = 0;
uint32_t FixupSize = 0;
uint8_t BundlePadding = 0;

public:
static bool classof(const MCFragment *F) {
MCFragment::FragmentType Kind = F->getKind();
Expand All @@ -136,6 +137,7 @@ class MCEncodedFragment : public MCFragment {
case MCFragment::FT_Dwarf:
case MCFragment::FT_DwarfFrame:
case MCFragment::FT_PseudoProbe:
case MCFragment::FT_CVInlineLines:
return true;
}
}
Expand Down Expand Up @@ -165,48 +167,33 @@ class MCEncodedFragment : public MCFragment {
HasInstructions = true;
this->STI = &STI;
}
};

/// Interface implemented by fragments that contain encoded instructions and/or
/// data and also have fixups registered.
///
template <unsigned ContentsSize, unsigned FixupsSize>
class MCEncodedFragmentWithFixups : public MCEncodedFragment {
SmallVector<char, ContentsSize> Contents;

/// The list of fixups in this fragment.
SmallVector<MCFixup, FixupsSize> Fixups;

protected:
MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
bool HasInstructions)
: MCEncodedFragment(FType, HasInstructions) {}

public:
SmallVectorImpl<char> &getContents() { return Contents; }
const SmallVectorImpl<char> &getContents() const { return Contents; }

void appendContents(ArrayRef<char> C) { Contents.append(C.begin(), C.end()); }
void appendContents(size_t Num, char Elt) { Contents.append(Num, Elt); }
void setContents(ArrayRef<char> C) { Contents.assign(C.begin(), C.end()); }

void addFixup(MCFixup Fixup) { Fixups.push_back(Fixup); }
SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }

static bool classof(const MCFragment *F) {
MCFragment::FragmentType Kind = F->getKind();
return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf ||
Kind == MCFragment::FT_DwarfFrame;
}
// Content-related functions manage parent's storage using ContentStart and
// ContentSize.
void clearContents() { ContentSize = 0; }
SmallVectorImpl<char> &getContentsForAppending();
void doneAppending();
void appendContents(ArrayRef<char> Contents);
void appendContents(size_t Num, char Elt);
void setContents(ArrayRef<char> Contents);
MutableArrayRef<char> getContents();
ArrayRef<char> getContents() const;

// Fixup-related functions manage parent's storage using FixupStart and
// FixupSize.
void clearFixups() { FixupSize = 0; }
void addFixup(MCFixup Fixup);
void appendFixups(ArrayRef<MCFixup> Fixups);
void setFixups(ArrayRef<MCFixup> Fixups);
MutableArrayRef<MCFixup> getFixups();
ArrayRef<MCFixup> getFixups() const;
};

/// Fragment for data and encoded instructions.
///
class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
class MCDataFragment : public MCEncodedFragment {
public:
MCDataFragment() : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false) {}
MCDataFragment() : MCEncodedFragment(FT_Data, false) {}

static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Data;
Expand All @@ -219,13 +206,13 @@ class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
/// A relaxable fragment holds on to its MCInst, since it may need to be
/// relaxed during the assembler layout and relaxation stage.
///
class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
class MCRelaxableFragment : public MCEncodedFragment {
/// The instruction this is a fragment for.
MCInst Inst;

public:
MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI)
: MCEncodedFragmentWithFixups(FT_Relaxable, true), Inst(Inst) {
: MCEncodedFragment(FT_Relaxable, true), Inst(Inst) {
this->STI = &STI;
}

Expand Down Expand Up @@ -374,7 +361,7 @@ class MCOrgFragment : public MCFragment {
}
};

class MCLEBFragment final : public MCEncodedFragmentWithFixups<8, 0> {
class MCLEBFragment final : public MCEncodedFragment {
/// True if this is a sleb128, false if uleb128.
bool IsSigned;

Expand All @@ -383,24 +370,19 @@ class MCLEBFragment final : public MCEncodedFragmentWithFixups<8, 0> {

public:
MCLEBFragment(const MCExpr &Value, bool IsSigned)
: MCEncodedFragmentWithFixups<8, 0>(FT_LEB, false), IsSigned(IsSigned),
Value(&Value) {
getContents().push_back(0);
}
: MCEncodedFragment(FT_LEB, false), IsSigned(IsSigned), Value(&Value) {}

const MCExpr &getValue() const { return *Value; }
void setValue(const MCExpr *Expr) { Value = Expr; }

bool isSigned() const { return IsSigned; }

/// @}

static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_LEB;
}
};

class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
class MCDwarfLineAddrFragment : public MCEncodedFragment {
/// The value of the difference between the two line numbers
/// between two .loc dwarf directives.
int64_t LineDelta;
Expand All @@ -411,8 +393,8 @@ class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {

public:
MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta)
: MCEncodedFragmentWithFixups<8, 1>(FT_Dwarf, false),
LineDelta(LineDelta), AddrDelta(&AddrDelta) {}
: MCEncodedFragment(FT_Dwarf, false), LineDelta(LineDelta),
AddrDelta(&AddrDelta) {}

int64_t getLineDelta() const { return LineDelta; }

Expand All @@ -423,15 +405,14 @@ class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
}
};

class MCDwarfCallFrameFragment : public MCEncodedFragmentWithFixups<8, 1> {
class MCDwarfCallFrameFragment : public MCEncodedFragment {
/// The expression for the difference of the two symbols that
/// make up the address delta between two .cfi_* dwarf directives.
const MCExpr *AddrDelta;

public:
MCDwarfCallFrameFragment(const MCExpr &AddrDelta)
: MCEncodedFragmentWithFixups<8, 1>(FT_DwarfFrame, false),
AddrDelta(&AddrDelta) {}
: MCEncodedFragment(FT_DwarfFrame, false), AddrDelta(&AddrDelta) {}

const MCExpr &getAddrDelta() const { return *AddrDelta; }
void setAddrDelta(const MCExpr *E) { AddrDelta = E; }
Expand Down Expand Up @@ -459,13 +440,12 @@ class MCSymbolIdFragment : public MCFragment {

/// Fragment representing the binary annotations produced by the
/// .cv_inline_linetable directive.
class MCCVInlineLineTableFragment : public MCFragment {
class MCCVInlineLineTableFragment : public MCEncodedFragment {
unsigned SiteFuncId;
unsigned StartFileId;
unsigned StartLineNum;
const MCSymbol *FnStartSym;
const MCSymbol *FnEndSym;
SmallString<8> Contents;

/// CodeViewContext has the real knowledge about this format, so let it access
/// our members.
Expand All @@ -475,23 +455,20 @@ class MCCVInlineLineTableFragment : public MCFragment {
MCCVInlineLineTableFragment(unsigned SiteFuncId, unsigned StartFileId,
unsigned StartLineNum, const MCSymbol *FnStartSym,
const MCSymbol *FnEndSym)
: MCFragment(FT_CVInlineLines, false), SiteFuncId(SiteFuncId),
: MCEncodedFragment(FT_CVInlineLines, false), SiteFuncId(SiteFuncId),
StartFileId(StartFileId), StartLineNum(StartLineNum),
FnStartSym(FnStartSym), FnEndSym(FnEndSym) {}

const MCSymbol *getFnStartSym() const { return FnStartSym; }
const MCSymbol *getFnEndSym() const { return FnEndSym; }

SmallString<8> &getContents() { return Contents; }
const SmallString<8> &getContents() const { return Contents; }

static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_CVInlineLines;
}
};

/// Fragment representing the .cv_def_range directive.
class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
class MCCVDefRangeFragment : public MCEncodedFragment {
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges;
StringRef FixedSizePortion;

Expand All @@ -503,8 +480,9 @@ class MCCVDefRangeFragment : public MCEncodedFragmentWithFixups<32, 4> {
MCCVDefRangeFragment(
ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> Ranges,
StringRef FixedSizePortion)
: MCEncodedFragmentWithFixups<32, 4>(FT_CVDefRange, false),
Ranges(Ranges), FixedSizePortion(FixedSizePortion) {}
: MCEncodedFragment(FT_CVDefRange, false),
Ranges(Ranges.begin(), Ranges.end()),
FixedSizePortion(FixedSizePortion) {}

ArrayRef<std::pair<const MCSymbol *, const MCSymbol *>> getRanges() const {
return Ranges;
Expand Down Expand Up @@ -556,15 +534,14 @@ class MCBoundaryAlignFragment : public MCFragment {
}
};

class MCPseudoProbeAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
class MCPseudoProbeAddrFragment : public MCEncodedFragment {
/// The expression for the difference of the two symbols that
/// make up the address delta between two .pseudoprobe directives.
const MCExpr *AddrDelta;

public:
MCPseudoProbeAddrFragment(const MCExpr *AddrDelta)
: MCEncodedFragmentWithFixups<8, 1>(FT_PseudoProbe, false),
AddrDelta(AddrDelta) {}
: MCEncodedFragment(FT_PseudoProbe, false), AddrDelta(AddrDelta) {}

const MCExpr &getAddrDelta() const { return *AddrDelta; }

Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/MC/MCSection.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class LLVM_ABI MCSection {
public:
friend MCAssembler;
friend MCObjectStreamer;
friend class MCEncodedFragment;
static constexpr unsigned NonUniqueID = ~0U;

enum SectionVariant {
Expand Down Expand Up @@ -116,6 +117,10 @@ class LLVM_ABI MCSection {
// subsections.
SmallVector<std::pair<unsigned, FragList>, 1> Subsections;

// Content and fixup storage for fragments
SmallVector<char, 0> ContentStorage;
SmallVector<MCFixup, 0> FixupStorage;

protected:
// TODO Make Name private when possible.
StringRef Name;
Expand Down
Loading
Loading