summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/MC/MCAssembler.h232
-rw-r--r--llvm/include/llvm/MC/MCELFStreamer.h2
-rw-r--r--llvm/include/llvm/MC/MCSection.h12
-rw-r--r--llvm/lib/MC/MCAssembler.cpp126
-rw-r--r--llvm/lib/MC/MCELFStreamer.cpp2
5 files changed, 188 insertions, 186 deletions
diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h
index 484f370515a..0642af837e7 100644
--- a/llvm/include/llvm/MC/MCAssembler.h
+++ b/llvm/include/llvm/MC/MCAssembler.h
@@ -49,7 +49,7 @@ class MCFragment : public ilist_node<MCFragment> {
void operator=(const MCFragment &) = delete;
public:
- enum FragmentType {
+ enum FragmentType : uint8_t {
FT_Align,
FT_Data,
FT_CompactEncodedInst,
@@ -65,6 +65,18 @@ public:
private:
FragmentType Kind;
+protected:
+ bool HasInstructions;
+
+private:
+ /// \brief Should this fragment be aligned to the end of a bundle?
+ bool AlignToBundleEnd;
+
+ uint8_t BundlePadding;
+
+ /// LayoutOrder - The layout order of this fragment.
+ unsigned LayoutOrder;
+
/// The data for the section this fragment is in.
MCSection *Parent;
@@ -81,18 +93,25 @@ private:
/// initialized.
uint64_t Offset;
- /// LayoutOrder - The layout order of this fragment.
- unsigned LayoutOrder;
-
/// @}
protected:
- MCFragment(FragmentType Kind, MCSection *Parent = nullptr);
+ MCFragment(FragmentType Kind, bool HasInstructions,
+ uint8_t BundlePadding, MCSection *Parent = nullptr);
-public:
- // Only for sentinel.
+ ~MCFragment();
+private:
+
+ // This is a friend so that the sentinal can be created.
+ friend struct ilist_sentinel_traits<MCFragment>;
MCFragment();
- virtual ~MCFragment();
+
+public:
+ /// Destroys the current fragment.
+ ///
+ /// This must be used instead of delete as MCFragment is non-virtual.
+ /// This method will dispatch to the appropriate subclass.
+ void destroy();
FragmentType getKind() const { return Kind; }
@@ -107,22 +126,22 @@ public:
/// \brief Does this fragment have instructions emitted into it? By default
/// this is false, but specific fragment types may set it to true.
- virtual bool hasInstructions() const { return false; }
+ bool hasInstructions() const { return HasInstructions; }
/// \brief Should this fragment be placed at the end of an aligned bundle?
- virtual bool alignToBundleEnd() const { return false; }
- virtual void setAlignToBundleEnd(bool V) {}
+ bool alignToBundleEnd() const { return AlignToBundleEnd; }
+ void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; }
/// \brief Get the padding size that must be inserted before this fragment.
/// Used for bundling. By default, no padding is inserted.
/// Note that padding size is restricted to 8 bits. This is an optimization
/// to reduce the amount of space used for each fragment. In practice, larger
/// padding should never be required.
- virtual uint8_t getBundlePadding() const { return 0; }
+ uint8_t getBundlePadding() const { return BundlePadding; }
/// \brief Set the padding size for this fragment. By default it's a no-op,
/// and only some fragments have a meaningful implementation.
- virtual void setBundlePadding(uint8_t N) {}
+ void setBundlePadding(uint8_t N) { BundlePadding = N; }
void dump();
};
@@ -131,22 +150,12 @@ public:
/// data.
///
class MCEncodedFragment : public MCFragment {
- virtual void anchor();
-
- uint8_t BundlePadding;
+protected:
+ MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions,
+ MCSection *Sec)
+ : MCFragment(FType, HasInstructions, 0, Sec) {}
public:
- MCEncodedFragment(MCFragment::FragmentType FType, MCSection *Sec = nullptr)
- : MCFragment(FType, Sec), BundlePadding(0) {}
- ~MCEncodedFragment() override;
-
- virtual SmallVectorImpl<char> &getContents() = 0;
- virtual const SmallVectorImpl<char> &getContents() const = 0;
-
- uint8_t getBundlePadding() const override { return BundlePadding; }
-
- void setBundlePadding(uint8_t N) override { BundlePadding = N; }
-
static bool classof(const MCFragment *F) {
MCFragment::FragmentType Kind = F->getKind();
switch (Kind) {
@@ -161,28 +170,52 @@ public:
};
/// Interface implemented by fragments that contain encoded instructions and/or
-/// data and also have fixups registered.
+/// data.
///
-class MCEncodedFragmentWithFixups : public MCEncodedFragment {
- void anchor() override;
+template<unsigned ContentsSize>
+class MCEncodedFragmentWithContents : public MCEncodedFragment {
+ SmallVector<char, ContentsSize> Contents;
+
+protected:
+ MCEncodedFragmentWithContents(MCFragment::FragmentType FType,
+ bool HasInstructions,
+ MCSection *Sec)
+ : MCEncodedFragment(FType, HasInstructions, Sec) {}
public:
- MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
- MCSection *Sec = nullptr)
- : MCEncodedFragment(FType, Sec) {}
+ SmallVectorImpl<char> &getContents() { return Contents; }
+ const SmallVectorImpl<char> &getContents() const { return Contents; }
+};
+
+/// Interface implemented by fragments that contain encoded instructions and/or
+/// data and also have fixups registered.
+///
+template<unsigned ContentsSize, unsigned FixupsSize>
+class MCEncodedFragmentWithFixups :
+ public MCEncodedFragmentWithContents<ContentsSize> {
- ~MCEncodedFragmentWithFixups() override;
+ /// Fixups - The list of fixups in this fragment.
+ SmallVector<MCFixup, FixupsSize> Fixups;
+protected:
+ MCEncodedFragmentWithFixups(MCFragment::FragmentType FType,
+ bool HasInstructions,
+ MCSection *Sec)
+ : MCEncodedFragmentWithContents<ContentsSize>(FType, HasInstructions,
+ Sec) {}
+
+public:
typedef SmallVectorImpl<MCFixup>::const_iterator const_fixup_iterator;
typedef SmallVectorImpl<MCFixup>::iterator fixup_iterator;
- virtual SmallVectorImpl<MCFixup> &getFixups() = 0;
- virtual const SmallVectorImpl<MCFixup> &getFixups() const = 0;
+ SmallVectorImpl<MCFixup> &getFixups() { return Fixups; }
+ const SmallVectorImpl<MCFixup> &getFixups() const { return Fixups; }
+
+ fixup_iterator fixup_begin() { return Fixups.begin(); }
+ const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
- virtual fixup_iterator fixup_begin() = 0;
- virtual const_fixup_iterator fixup_begin() const = 0;
- virtual fixup_iterator fixup_end() = 0;
- virtual const_fixup_iterator fixup_end() const = 0;
+ fixup_iterator fixup_end() { return Fixups.end(); }
+ const_fixup_iterator fixup_end() const { return Fixups.end(); }
static bool classof(const MCFragment *F) {
MCFragment::FragmentType Kind = F->getKind();
@@ -192,43 +225,12 @@ public:
/// Fragment for data and encoded instructions.
///
-class MCDataFragment : public MCEncodedFragmentWithFixups {
- void anchor() override;
-
- /// \brief Does this fragment contain encoded instructions anywhere in it?
- bool HasInstructions;
-
- /// \brief Should this fragment be aligned to the end of a bundle?
- bool AlignToBundleEnd;
-
- SmallVector<char, 32> Contents;
-
- /// Fixups - The list of fixups in this fragment.
- SmallVector<MCFixup, 4> Fixups;
-
+class MCDataFragment : public MCEncodedFragmentWithFixups<32, 4> {
public:
MCDataFragment(MCSection *Sec = nullptr)
- : MCEncodedFragmentWithFixups(FT_Data, Sec), HasInstructions(false),
- AlignToBundleEnd(false) {}
-
- SmallVectorImpl<char> &getContents() override { return Contents; }
- const SmallVectorImpl<char> &getContents() const override { return Contents; }
-
- SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; }
+ : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {}
- const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; }
-
- bool hasInstructions() const override { return HasInstructions; }
- virtual void setHasInstructions(bool V) { HasInstructions = V; }
-
- bool alignToBundleEnd() const override { return AlignToBundleEnd; }
- void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
-
- fixup_iterator fixup_begin() override { return Fixups.begin(); }
- const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
-
- fixup_iterator fixup_end() override { return Fixups.end(); }
- const_fixup_iterator fixup_end() const override { return Fixups.end(); }
+ void setHasInstructions(bool V) { HasInstructions = V; }
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Data;
@@ -240,27 +242,12 @@ public:
/// it can be used instead of MCDataFragment and lead to lower memory
/// consumption.
///
-class MCCompactEncodedInstFragment : public MCEncodedFragment {
- void anchor() override;
-
- /// \brief Should this fragment be aligned to the end of a bundle?
- bool AlignToBundleEnd;
-
- SmallVector<char, 4> Contents;
-
+class MCCompactEncodedInstFragment : public MCEncodedFragmentWithContents<4> {
public:
MCCompactEncodedInstFragment(MCSection *Sec = nullptr)
- : MCEncodedFragment(FT_CompactEncodedInst, Sec), AlignToBundleEnd(false) {
+ : MCEncodedFragmentWithContents(FT_CompactEncodedInst, true, Sec) {
}
- bool hasInstructions() const override { return true; }
-
- SmallVectorImpl<char> &getContents() override { return Contents; }
- const SmallVectorImpl<char> &getContents() const override { return Contents; }
-
- bool alignToBundleEnd() const override { return AlignToBundleEnd; }
- void setAlignToBundleEnd(bool V) override { AlignToBundleEnd = V; }
-
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_CompactEncodedInst;
}
@@ -269,8 +256,7 @@ public:
/// 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 {
- void anchor() override;
+class MCRelaxableFragment : public MCEncodedFragmentWithFixups<8, 1> {
/// Inst - The instruction this is a fragment for.
MCInst Inst;
@@ -280,48 +266,32 @@ class MCRelaxableFragment : public MCEncodedFragmentWithFixups {
/// in the assembler are not seen here.
const MCSubtargetInfo STI;
- /// Contents - Binary data for the currently encoded instruction.
- SmallVector<char, 8> Contents;
-
- /// Fixups - The list of fixups in this fragment.
- SmallVector<MCFixup, 1> Fixups;
-
public:
MCRelaxableFragment(const MCInst &Inst, const MCSubtargetInfo &STI,
MCSection *Sec = nullptr)
- : MCEncodedFragmentWithFixups(FT_Relaxable, Sec), Inst(Inst), STI(STI) {}
-
- SmallVectorImpl<char> &getContents() override { return Contents; }
- const SmallVectorImpl<char> &getContents() const override { return Contents; }
+ : MCEncodedFragmentWithFixups(FT_Relaxable, true, Sec),
+ Inst(Inst), STI(STI) {}
const MCInst &getInst() const { return Inst; }
void setInst(const MCInst &Value) { Inst = Value; }
const MCSubtargetInfo &getSubtargetInfo() { return STI; }
- SmallVectorImpl<MCFixup> &getFixups() override { return Fixups; }
-
- const SmallVectorImpl<MCFixup> &getFixups() const override { return Fixups; }
-
- bool hasInstructions() const override { return true; }
-
- fixup_iterator fixup_begin() override { return Fixups.begin(); }
- const_fixup_iterator fixup_begin() const override { return Fixups.begin(); }
-
- fixup_iterator fixup_end() override { return Fixups.end(); }
- const_fixup_iterator fixup_end() const override { return Fixups.end(); }
-
static bool classof(const MCFragment *F) {
return F->getKind() == MCFragment::FT_Relaxable;
}
};
class MCAlignFragment : public MCFragment {
- virtual void anchor();
/// Alignment - The alignment to ensure, in bytes.
unsigned Alignment;
+ /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
+ /// of using the provided value. The exact interpretation of this flag is
+ /// target dependent.
+ bool EmitNops : 1;
+
/// Value - Value to use for filling padding bytes.
int64_t Value;
@@ -332,16 +302,12 @@ class MCAlignFragment : public MCFragment {
/// cannot be satisfied in this width then this fragment is ignored.
unsigned MaxBytesToEmit;
- /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
- /// of using the provided value. The exact interpretation of this flag is
- /// target dependent.
- bool EmitNops : 1;
-
public:
MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize,
unsigned MaxBytesToEmit, MCSection *Sec = nullptr)
- : MCFragment(FT_Align, Sec), Alignment(Alignment), Value(Value),
- ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit), EmitNops(false) {}
+ : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment),
+ EmitNops(false), Value(Value),
+ ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {}
/// \name Accessors
/// @{
@@ -365,7 +331,6 @@ public:
};
class MCFillFragment : public MCFragment {
- virtual void anchor();
/// Value - Value to use for filling bytes.
int64_t Value;
@@ -380,7 +345,7 @@ class MCFillFragment : public MCFragment {
public:
MCFillFragment(int64_t Value, unsigned ValueSize, uint64_t Size,
MCSection *Sec = nullptr)
- : MCFragment(FT_Fill, Sec), Value(Value), ValueSize(ValueSize),
+ : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(ValueSize),
Size(Size) {
assert((!ValueSize || (Size % ValueSize) == 0) &&
"Fill size must be a multiple of the value size!");
@@ -403,7 +368,6 @@ public:
};
class MCOrgFragment : public MCFragment {
- virtual void anchor();
/// Offset - The offset this fragment should start at.
const MCExpr *Offset;
@@ -413,7 +377,7 @@ class MCOrgFragment : public MCFragment {
public:
MCOrgFragment(const MCExpr &Offset, int8_t Value, MCSection *Sec = nullptr)
- : MCFragment(FT_Org, Sec), Offset(&Offset), Value(Value) {}
+ : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value) {}
/// \name Accessors
/// @{
@@ -430,7 +394,6 @@ public:
};
class MCLEBFragment : public MCFragment {
- virtual void anchor();
/// Value - The value this fragment should contain.
const MCExpr *Value;
@@ -442,7 +405,7 @@ class MCLEBFragment : public MCFragment {
public:
MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr)
- : MCFragment(FT_LEB, Sec), Value(&Value_), IsSigned(IsSigned_) {
+ : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) {
Contents.push_back(0);
}
@@ -464,7 +427,6 @@ public:
};
class MCDwarfLineAddrFragment : public MCFragment {
- virtual void anchor();
/// LineDelta - the value of the difference between the two line numbers
/// between two .loc dwarf directives.
@@ -479,7 +441,8 @@ class MCDwarfLineAddrFragment : public MCFragment {
public:
MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta,
MCSection *Sec = nullptr)
- : MCFragment(FT_Dwarf, Sec), LineDelta(LineDelta), AddrDelta(&AddrDelta) {
+ : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta),
+ AddrDelta(&AddrDelta) {
Contents.push_back(0);
}
@@ -501,7 +464,6 @@ public:
};
class MCDwarfCallFrameFragment : public MCFragment {
- virtual void anchor();
/// AddrDelta - The expression for the difference of the two symbols that
/// make up the address delta between two .cfi_* dwarf directives.
@@ -511,7 +473,7 @@ class MCDwarfCallFrameFragment : public MCFragment {
public:
MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
- : MCFragment(FT_DwarfFrame, Sec), AddrDelta(&AddrDelta) {
+ : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) {
Contents.push_back(0);
}
@@ -531,13 +493,11 @@ public:
};
class MCSafeSEHFragment : public MCFragment {
- virtual void anchor();
-
const MCSymbol *Sym;
public:
MCSafeSEHFragment(const MCSymbol *Sym, MCSection *Sec = nullptr)
- : MCFragment(FT_SafeSEH, Sec), Sym(Sym) {}
+ : MCFragment(FT_SafeSEH, false, 0, Sec), Sym(Sym) {}
/// \name Accessors
/// @{
diff --git a/llvm/include/llvm/MC/MCELFStreamer.h b/llvm/include/llvm/MC/MCELFStreamer.h
index 241db0dc9cd..a5b257f5958 100644
--- a/llvm/include/llvm/MC/MCELFStreamer.h
+++ b/llvm/include/llvm/MC/MCELFStreamer.h
@@ -93,7 +93,7 @@ private:
void fixSymbolsInTLSFixups(const MCExpr *expr);
/// \brief Merge the content of the fragment \p EF into the fragment \p DF.
- void mergeFragment(MCDataFragment *, MCEncodedFragmentWithFixups *);
+ void mergeFragment(MCDataFragment *, MCDataFragment *);
bool SeenIdent;
diff --git a/llvm/include/llvm/MC/MCSection.h b/llvm/include/llvm/MC/MCSection.h
index 5f6e8ec1d50..2d0d4dfc591 100644
--- a/llvm/include/llvm/MC/MCSection.h
+++ b/llvm/include/llvm/MC/MCSection.h
@@ -31,6 +31,18 @@ class MCSection;
class MCSymbol;
class raw_ostream;
+template<>
+struct ilist_node_traits<MCFragment> {
+ MCFragment *createNode(const MCFragment &V);
+ static void deleteNode(MCFragment *V);
+
+ void addNodeToList(MCFragment *) {}
+ void removeNodeFromList(MCFragment *) {}
+ void transferNodesFromList(ilist_node_traits & /*SrcTraits*/,
+ ilist_iterator<MCFragment> /*first*/,
+ ilist_iterator<MCFragment> /*last*/) {}
+};
+
/// Instances of this class represent a uniqued identifier for a section in the
/// current translation unit. The MCContext class uniques and creates these.
class MCSection {
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index df416710182..76be67cafc5 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -262,26 +262,64 @@ uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler,
/* *** */
-MCFragment::MCFragment() : Kind(FragmentType(~0)) {
+void ilist_node_traits<MCFragment>::deleteNode(MCFragment *V) {
+ V->destroy();
}
-MCFragment::~MCFragment() {
+MCFragment::MCFragment() : Kind(FragmentType(~0)), HasInstructions(false),
+ AlignToBundleEnd(false), BundlePadding(0) {
}
-MCFragment::MCFragment(FragmentType Kind, MCSection *Parent)
- : Kind(Kind), Parent(Parent), Atom(nullptr), Offset(~UINT64_C(0)) {
+MCFragment::~MCFragment() { }
+
+MCFragment::MCFragment(FragmentType Kind, bool HasInstructions,
+ uint8_t BundlePadding, MCSection *Parent)
+ : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false),
+ BundlePadding(BundlePadding), Parent(Parent), Atom(nullptr),
+ Offset(~UINT64_C(0)) {
if (Parent)
Parent->getFragmentList().push_back(this);
}
-/* *** */
-
-MCEncodedFragment::~MCEncodedFragment() {
-}
-
-/* *** */
+void MCFragment::destroy() {
+ // First check if we are the sentinal.
+ if (Kind == FragmentType(~0)) {
+ delete this;
+ return;
+ }
-MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() {
+ switch (Kind) {
+ case FT_Align:
+ delete cast<MCAlignFragment>(this);
+ return;
+ case FT_Data:
+ delete cast<MCDataFragment>(this);
+ return;
+ case FT_CompactEncodedInst:
+ delete cast<MCCompactEncodedInstFragment>(this);
+ return;
+ case FT_Fill:
+ delete cast<MCFillFragment>(this);
+ return;
+ case FT_Relaxable:
+ delete cast<MCRelaxableFragment>(this);
+ return;
+ case FT_Org:
+ delete cast<MCOrgFragment>(this);
+ return;
+ case FT_Dwarf:
+ delete cast<MCDwarfLineAddrFragment>(this);
+ return;
+ case FT_DwarfFrame:
+ delete cast<MCDwarfCallFrameFragment>(this);
+ return;
+ case FT_LEB:
+ delete cast<MCLEBFragment>(this);
+ return;
+ case FT_SafeSEH:
+ delete cast<MCSafeSEHFragment>(this);
+ return;
+ }
}
/* *** */
@@ -454,9 +492,11 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
const MCFragment &F) const {
switch (F.getKind()) {
case MCFragment::FT_Data:
+ return cast<MCDataFragment>(F).getContents().size();
case MCFragment::FT_Relaxable:
+ return cast<MCRelaxableFragment>(F).getContents().size();
case MCFragment::FT_CompactEncodedInst:
- return cast<MCEncodedFragment>(F).getContents().size();
+ return cast<MCCompactEncodedInstFragment>(F).getContents().size();
case MCFragment::FT_Fill:
return cast<MCFillFragment>(F).getSize();
@@ -562,13 +602,6 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
}
}
-/// \brief Write the contents of a fragment to the given object writer. Expects
-/// a MCEncodedFragment.
-static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) {
- const MCEncodedFragment &EF = cast<MCEncodedFragment>(F);
- OW->writeBytes(EF.getContents());
-}
-
void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) {
bool New = !Symbol.isRegistered();
if (Created)
@@ -671,17 +704,17 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
case MCFragment::FT_Data:
++stats::EmittedDataFragments;
- writeFragmentContents(F, OW);
+ OW->writeBytes(cast<MCDataFragment>(F).getContents());
break;
case MCFragment::FT_Relaxable:
++stats::EmittedRelaxableFragments;
- writeFragmentContents(F, OW);
+ OW->writeBytes(cast<MCRelaxableFragment>(F).getContents());
break;
case MCFragment::FT_CompactEncodedInst:
++stats::EmittedCompactEncodedInstFragments;
- writeFragmentContents(F, OW);
+ OW->writeBytes(cast<MCCompactEncodedInstFragment>(F).getContents());
break;
case MCFragment::FT_Fill: {
@@ -870,18 +903,29 @@ void MCAssembler::Finish() {
for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) {
for (MCSection::iterator it2 = it->begin(), ie2 = it->end(); it2 != ie2;
++it2) {
- MCEncodedFragmentWithFixups *F =
- dyn_cast<MCEncodedFragmentWithFixups>(it2);
- if (F) {
- for (MCEncodedFragmentWithFixups::fixup_iterator it3 = F->fixup_begin(),
- ie3 = F->fixup_end(); it3 != ie3; ++it3) {
- MCFixup &Fixup = *it3;
- uint64_t FixedValue;
- bool IsPCRel;
- std::tie(FixedValue, IsPCRel) = handleFixup(Layout, *F, Fixup);
- getBackend().applyFixup(Fixup, F->getContents().data(),
- F->getContents().size(), FixedValue, IsPCRel);
- }
+ MCEncodedFragment *F = dyn_cast<MCEncodedFragment>(it2);
+ // Data and relaxable fragments both have fixups. So only process
+ // those here.
+ // FIXME: Is there a better way to do this? MCEncodedFragmentWithFixups
+ // being templated makes this tricky.
+ if (!F || isa<MCCompactEncodedInstFragment>(F))
+ continue;
+ ArrayRef<MCFixup> Fixups;
+ MutableArrayRef<char> Contents;
+ if (auto *FragWithFixups = dyn_cast<MCDataFragment>(F)) {
+ Fixups = FragWithFixups->getFixups();
+ Contents = FragWithFixups->getContents();
+ } else if (auto *FragWithFixups = dyn_cast<MCRelaxableFragment>(F)) {
+ Fixups = FragWithFixups->getFixups();
+ Contents = FragWithFixups->getContents();
+ } else
+ llvm_unreachable("Unknow fragment with fixups!");
+ for (const MCFixup &Fixup : Fixups) {
+ uint64_t FixedValue;
+ bool IsPCRel;
+ std::tie(FixedValue, IsPCRel) = handleFixup(Layout, *F, Fixup);
+ getBackend().applyFixup(Fixup, Contents.data(),
+ Contents.size(), FixedValue, IsPCRel);
}
}
}
@@ -1218,17 +1262,3 @@ void MCAssembler::dump() {
OS << "]>\n";
}
#endif
-
-// anchors for MC*Fragment vtables
-void MCEncodedFragment::anchor() { }
-void MCEncodedFragmentWithFixups::anchor() { }
-void MCDataFragment::anchor() { }
-void MCCompactEncodedInstFragment::anchor() { }
-void MCRelaxableFragment::anchor() { }
-void MCAlignFragment::anchor() { }
-void MCFillFragment::anchor() { }
-void MCOrgFragment::anchor() { }
-void MCLEBFragment::anchor() { }
-void MCSafeSEHFragment::anchor() { }
-void MCDwarfLineAddrFragment::anchor() { }
-void MCDwarfCallFrameFragment::anchor() { }
diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp
index e0f4a2ae16a..fe9ac21e17f 100644
--- a/llvm/lib/MC/MCELFStreamer.cpp
+++ b/llvm/lib/MC/MCELFStreamer.cpp
@@ -45,7 +45,7 @@ MCELFStreamer::~MCELFStreamer() {
}
void MCELFStreamer::mergeFragment(MCDataFragment *DF,
- MCEncodedFragmentWithFixups *EF) {
+ MCDataFragment *EF) {
MCAssembler &Assembler = getAssembler();
if (Assembler.isBundlingEnabled() && Assembler.getRelaxAll()) {
OpenPOWER on IntegriCloud