From a31a894eede101b92dabd67d553d901db50e7ab5 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Fri, 7 Dec 2012 19:13:57 +0000 Subject: [PATCH] Refactor MCInstFragment and MCDataFragment to adhere to a common interface, which removes code duplication and prepares the ground for future additions. Full discussion: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20121203/158233.html llvm-svn: 169626 --- llvm/include/llvm/MC/MCAssembler.h | 95 ++++++++++++++++++++------------------ llvm/lib/MC/MCAssembler.cpp | 75 ++++++++++++++---------------- llvm/lib/MC/MCELFStreamer.cpp | 2 +- llvm/lib/MC/MCMachOStreamer.cpp | 2 +- llvm/lib/MC/MCObjectStreamer.cpp | 14 +++--- llvm/lib/MC/MCPureStreamer.cpp | 4 +- llvm/lib/MC/WinCOFFStreamer.cpp | 9 ++-- 7 files changed, 102 insertions(+), 99 deletions(-) diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h index 266e0c7..a308030 100644 --- a/llvm/include/llvm/MC/MCAssembler.h +++ b/llvm/include/llvm/MC/MCAssembler.h @@ -102,7 +102,35 @@ public: void dump(); }; -class MCDataFragment : public MCFragment { +class MCEncodedFragment : public MCFragment { + virtual void anchor(); +public: + MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0) + : MCFragment(FType, SD) { + } + virtual ~MCEncodedFragment(); + + typedef SmallVectorImpl::const_iterator const_fixup_iterator; + typedef SmallVectorImpl::iterator fixup_iterator; + + virtual SmallString<32> &getContents() = 0; + virtual const SmallString<32> &getContents() const = 0; + + virtual SmallVectorImpl &getFixups() = 0; + virtual const SmallVectorImpl &getFixups() const = 0; + + 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; + + static bool classof(const MCFragment *F) { + MCFragment::FragmentType Kind = F->getKind(); + return Kind == MCFragment::FT_Inst || Kind == MCFragment::FT_Data; + } +}; + +class MCDataFragment : public MCEncodedFragment { virtual void anchor(); SmallString<32> Contents; @@ -110,27 +138,19 @@ class MCDataFragment : public MCFragment { SmallVector Fixups; public: - typedef SmallVectorImpl::const_iterator const_fixup_iterator; - typedef SmallVectorImpl::iterator fixup_iterator; - -public: - MCDataFragment(MCSectionData *SD = 0) : MCFragment(FT_Data, SD) {} - - /// @name Accessors - /// @{ + MCDataFragment(MCSectionData *SD = 0) + : MCEncodedFragment(FT_Data, SD) { + } SmallString<32> &getContents() { return Contents; } const SmallString<32> &getContents() const { return Contents; } - /// @} - /// @name Fixup Access - /// @{ + SmallVectorImpl &getFixups() { + return Fixups; + } - void addFixup(MCFixup Fixup) { - // Enforce invariant that fixups are in offset order. - assert((Fixups.empty() || Fixup.getOffset() >= Fixups.back().getOffset()) && - "Fixups must be added in order!"); - Fixups.push_back(Fixup); + const SmallVectorImpl &getFixups() const { + return Fixups; } fixup_iterator fixup_begin() { return Fixups.begin(); } @@ -139,55 +159,42 @@ public: fixup_iterator fixup_end() {return Fixups.end();} const_fixup_iterator fixup_end() const {return Fixups.end();} - /// @} - static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Data; } }; -// FIXME: This current incarnation of MCInstFragment doesn't make much sense, as -// it is almost entirely a duplicate of MCDataFragment. If we decide to stick -// with this approach (as opposed to making MCInstFragment a very light weight -// object with just the MCInst and a code size, then we should just change -// MCDataFragment to have an optional MCInst at its end. -class MCInstFragment : public MCFragment { +class MCInstFragment : public MCEncodedFragment { virtual void anchor(); /// Inst - The instruction this is a fragment for. MCInst Inst; - /// Code - Binary data for the currently encoded instruction. - SmallString<8> Code; + /// Contents - Binary data for the currently encoded instruction. + SmallString<32> Contents; /// Fixups - The list of fixups in this fragment. SmallVector Fixups; public: - typedef SmallVectorImpl::const_iterator const_fixup_iterator; - typedef SmallVectorImpl::iterator fixup_iterator; - -public: MCInstFragment(const MCInst &_Inst, MCSectionData *SD = 0) - : MCFragment(FT_Inst, SD), Inst(_Inst) { + : MCEncodedFragment(FT_Inst, SD), Inst(_Inst) { } - /// @name Accessors - /// @{ - - SmallVectorImpl &getCode() { return Code; } - const SmallVectorImpl &getCode() const { return Code; } + SmallString<32> &getContents() { return Contents; } + const SmallString<32> &getContents() const { return Contents; } - unsigned getInstSize() const { return Code.size(); } + unsigned getInstSize() const { return Contents.size(); } const MCInst &getInst() const { return Inst; } void setInst(const MCInst& Value) { Inst = Value; } - /// @} - /// @name Fixup Access - /// @{ + SmallVectorImpl &getFixups() { + return Fixups; + } - SmallVectorImpl &getFixups() { return Fixups; } - const SmallVectorImpl &getFixups() const { return Fixups; } + const SmallVectorImpl &getFixups() const { + return Fixups; + } fixup_iterator fixup_begin() { return Fixups.begin(); } const_fixup_iterator fixup_begin() const { return Fixups.begin(); } @@ -195,8 +202,6 @@ public: fixup_iterator fixup_end() {return Fixups.end();} const_fixup_iterator fixup_end() const {return Fixups.end();} - /// @} - static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Inst; } diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index 5032e6f..b2136e5 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -168,6 +168,11 @@ MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) /* *** */ +MCEncodedFragment::~MCEncodedFragment() { +} + +/* *** */ + MCSectionData::MCSectionData() : Section(0) {} MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) @@ -382,9 +387,16 @@ void MCAsmLayout::LayoutFragment(MCFragment *F) { LastValidFragment[F->getParent()] = F; } -/// WriteFragmentData - Write the \p F data to the output file. -static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, - const 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) { + MCEncodedFragment &EF = cast(F); + OW->WriteBytes(EF.getContents().str()); +} + +/// \brief Write the fragment \p F to the output file. +static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, + const MCFragment &F) { MCObjectWriter *OW = &Asm.getWriter(); uint64_t Start = OW->getStream().tell(); (void) Start; @@ -433,13 +445,15 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, break; } - case MCFragment::FT_Data: { + case MCFragment::FT_Data: ++stats::EmittedDataFragments; - MCDataFragment &DF = cast(F); - assert(FragmentSize == DF.getContents().size() && "Invalid size!"); - OW->WriteBytes(DF.getContents().str()); + writeFragmentContents(F, OW); + break; + + case MCFragment::FT_Inst: + ++stats::EmittedInstFragments; + writeFragmentContents(F, OW); break; - } case MCFragment::FT_Fill: { MCFillFragment &FF = cast(F); @@ -458,13 +472,6 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, break; } - case MCFragment::FT_Inst: { - ++stats::EmittedInstFragments; - MCInstFragment &IF = cast(F); - OW->WriteBytes(StringRef(IF.getCode().begin(), IF.getCode().size())); - break; - } - case MCFragment::FT_LEB: { MCLEBFragment &LF = cast(F); OW->WriteBytes(LF.getContents().str()); @@ -538,9 +545,9 @@ void MCAssembler::writeSectionData(const MCSectionData *SD, uint64_t Start = getWriter().getStream().tell(); (void)Start; - for (MCSectionData::const_iterator it = SD->begin(), - ie = SD->end(); it != ie; ++it) - WriteFragmentData(*this, Layout, *it); + for (MCSectionData::const_iterator it = SD->begin(), ie = SD->end(); + it != ie; ++it) + writeFragment(*this, Layout, *it); assert(getWriter().getStream().tell() - Start == Layout.getSectionAddressSize(SD)); @@ -617,24 +624,14 @@ void MCAssembler::Finish() { for (MCAssembler::iterator it = begin(), ie = end(); it != ie; ++it) { for (MCSectionData::iterator it2 = it->begin(), ie2 = it->end(); it2 != ie2; ++it2) { - MCDataFragment *DF = dyn_cast(it2); - if (DF) { - for (MCDataFragment::fixup_iterator it3 = DF->fixup_begin(), - ie3 = DF->fixup_end(); it3 != ie3; ++it3) { - MCFixup &Fixup = *it3; - uint64_t FixedValue = handleFixup(Layout, *DF, Fixup); - getBackend().applyFixup(Fixup, DF->getContents().data(), - DF->getContents().size(), FixedValue); - } - } - MCInstFragment *IF = dyn_cast(it2); - if (IF) { - for (MCInstFragment::fixup_iterator it3 = IF->fixup_begin(), - ie3 = IF->fixup_end(); it3 != ie3; ++it3) { + MCEncodedFragment *F = dyn_cast(it2); + if (F) { + for (MCEncodedFragment::fixup_iterator it3 = F->fixup_begin(), + ie3 = F->fixup_end(); it3 != ie3; ++it3) { MCFixup &Fixup = *it3; - uint64_t FixedValue = handleFixup(Layout, *IF, Fixup); - getBackend().applyFixup(Fixup, IF->getCode().data(), - IF->getCode().size(), FixedValue); + uint64_t FixedValue = handleFixup(Layout, *F, Fixup); + getBackend().applyFixup(Fixup, F->getContents().data(), + F->getContents().size(), FixedValue); } } } @@ -704,11 +701,8 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, // Update the instruction fragment. IF.setInst(Relaxed); - IF.getCode() = Code; - IF.getFixups().clear(); - // FIXME: Eliminate copy. - for (unsigned i = 0, e = Fixups.size(); i != e; ++i) - IF.getFixups().push_back(Fixups[i]); + IF.getContents() = Code; + IF.getFixups() = Fixups; return true; } @@ -977,6 +971,7 @@ void MCAssembler::dump() { #endif // anchors for MC*Fragment vtables +void MCEncodedFragment::anchor() { } void MCDataFragment::anchor() { } void MCInstFragment::anchor() { } void MCAlignFragment::anchor() { } diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index b1952bf..8b9bdb1 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -345,7 +345,7 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) { // Add the fixups and data. for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); - DF->addFixup(Fixups[i]); + DF->getFixups().push_back(Fixups[i]); } DF->getContents().append(Code.begin(), Code.end()); } diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index cc6c853..f279e74 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -368,7 +368,7 @@ void MCMachOStreamer::EmitInstToData(const MCInst &Inst) { // Add the fixups and data. for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); - DF->addFixup(Fixups[i]); + DF->getFixups().push_back(Fixups[i]); } DF->getContents().append(Code.begin(), Code.end()); } diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 08200eb..c2171ff 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -99,9 +99,9 @@ void MCObjectStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, EmitIntValue(AbsValue, Size, AddrSpace); return; } - DF->addFixup(MCFixup::Create(DF->getContents().size(), - Value, - MCFixup::getKindForSize(Size, false))); + DF->getFixups().push_back( + MCFixup::Create(DF->getContents().size(), Value, + MCFixup::getKindForSize(Size, false))); DF->getContents().resize(DF->getContents().size() + Size, 0); } @@ -204,7 +204,7 @@ void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) { raw_svector_ostream VecOS(Code); getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, IF->getFixups()); VecOS.flush(); - IF->getCode().append(Code.begin(), Code.end()); + IF->getContents().append(Code.begin(), Code.end()); } void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta, @@ -288,7 +288,8 @@ bool MCObjectStreamer::EmitValueToOffset(const MCExpr *Offset, void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); - DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); + DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), + Value, FK_GPRel_4)); DF->getContents().resize(DF->getContents().size() + 4, 0); } @@ -296,7 +297,8 @@ void MCObjectStreamer::EmitGPRel32Value(const MCExpr *Value) { void MCObjectStreamer::EmitGPRel64Value(const MCExpr *Value) { MCDataFragment *DF = getOrCreateDataFragment(); - DF->addFixup(MCFixup::Create(DF->getContents().size(), Value, FK_GPRel_4)); + DF->getFixups().push_back(MCFixup::Create(DF->getContents().size(), + Value, FK_GPRel_4)); DF->getContents().resize(DF->getContents().size() + 8, 0); } diff --git a/llvm/lib/MC/MCPureStreamer.cpp b/llvm/lib/MC/MCPureStreamer.cpp index fd9ccf7..1563bdd 100644 --- a/llvm/lib/MC/MCPureStreamer.cpp +++ b/llvm/lib/MC/MCPureStreamer.cpp @@ -194,7 +194,7 @@ void MCPureStreamer::EmitInstToFragment(const MCInst &Inst) { getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups); VecOS.flush(); - IF->getCode() = Code; + IF->getContents() = Code; IF->getFixups() = Fixups; } @@ -210,7 +210,7 @@ void MCPureStreamer::EmitInstToData(const MCInst &Inst) { // Add the fixups and data. for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size()); - DF->addFixup(Fixups[i]); + DF->getFixups().push_back(Fixups[i]); } DF->getContents().append(Code.begin(), Code.end()); } diff --git a/llvm/lib/MC/WinCOFFStreamer.cpp b/llvm/lib/MC/WinCOFFStreamer.cpp index 8c8ae3f..359b388 100644 --- a/llvm/lib/MC/WinCOFFStreamer.cpp +++ b/llvm/lib/MC/WinCOFFStreamer.cpp @@ -288,9 +288,10 @@ void WinCOFFStreamer::EmitCOFFSecRel32(MCSymbol const *Symbol) { MCDataFragment *DF = getOrCreateDataFragment(); - DF->addFixup(MCFixup::Create(DF->getContents().size(), - MCSymbolRefExpr::Create (Symbol, getContext ()), - FK_SecRel_4)); + DF->getFixups().push_back( + MCFixup::Create(DF->getContents().size(), + MCSymbolRefExpr::Create (Symbol, getContext ()), + FK_SecRel_4)); DF->getContents().resize(DF->getContents().size() + 4, 0); } @@ -339,7 +340,7 @@ void WinCOFFStreamer::EmitInstruction(const MCInst &Instruction) { MCInstFragment *Fragment = new MCInstFragment(Instruction, getCurrentSectionData()); - raw_svector_ostream VecOS(Fragment->getCode()); + raw_svector_ostream VecOS(Fragment->getContents()); getAssembler().getEmitter().EncodeInstruction(Instruction, VecOS, Fragment->getFixups()); -- 2.7.4