diff options
Diffstat (limited to 'lib/MC/MCAssembler.cpp')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 148 |
1 files changed, 79 insertions, 69 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 726ec5aba5..8f8ec151e5 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -9,31 +9,41 @@ #define DEBUG_TYPE "assembler" #include "llvm/MC/MCAssembler.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/Twine.h" +#include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmLayout.h" #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDwarf.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCValue.h" -#include "llvm/MC/MCDwarf.h" -#include "llvm/MC/MCAsmBackend.h" -#include "llvm/ADT/Statistic.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/ADT/Twine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/TargetRegistry.h" #include "llvm/Support/LEB128.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; namespace { namespace stats { -STATISTIC(EmittedFragments, "Number of emitted assembler fragments"); +STATISTIC(EmittedFragments, "Number of emitted assembler fragments - total"); +STATISTIC(EmittedInstFragments, + "Number of emitted assembler fragments - instruction"); +STATISTIC(EmittedDataFragments, + "Number of emitted assembler fragments - data"); +STATISTIC(EmittedAlignFragments, + "Number of emitted assembler fragments - align"); +STATISTIC(EmittedFillFragments, + "Number of emitted assembler fragments - fill"); +STATISTIC(EmittedOrgFragments, + "Number of emitted assembler fragments - org"); STATISTIC(evaluateFixup, "Number of evaluated fixups"); STATISTIC(FragmentLayouts, "Number of fragment layouts"); STATISTIC(ObjectBytes, "Number of emitted object file bytes"); @@ -70,7 +80,7 @@ bool MCAsmLayout::isFragmentUpToDate(const MCFragment *F) const { return F->getLayoutOrder() <= LastValid->getLayoutOrder(); } -void MCAsmLayout::Invalidate(MCFragment *F) { +void MCAsmLayout::invalidateFragmentsAfter(MCFragment *F) { // If this fragment wasn't already up-to-date, we don't need to do anything. if (!isFragmentUpToDate(F)) return; @@ -166,6 +176,11 @@ MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) /* *** */ +MCEncodedFragment::~MCEncodedFragment() { +} + +/* *** */ + MCSectionData::MCSectionData() : Section(0) {} MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) @@ -380,9 +395,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<MCEncodedFragment>(F); + OW->WriteBytes(EF.getContents()); +} + +/// \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; @@ -393,6 +415,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); switch (F.getKind()) { case MCFragment::FT_Align: { + ++stats::EmittedAlignFragments; MCAlignFragment &AF = cast<MCAlignFragment>(F); uint64_t Count = FragmentSize / AF.getValueSize(); @@ -431,14 +454,18 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, break; } - case MCFragment::FT_Data: { - MCDataFragment &DF = cast<MCDataFragment>(F); - assert(FragmentSize == DF.getContents().size() && "Invalid size!"); - OW->WriteBytes(DF.getContents().str()); + case MCFragment::FT_Data: + ++stats::EmittedDataFragments; + writeFragmentContents(F, OW); + break; + + case MCFragment::FT_Inst: + ++stats::EmittedInstFragments; + writeFragmentContents(F, OW); break; - } case MCFragment::FT_Fill: { + ++stats::EmittedFillFragments; MCFillFragment &FF = cast<MCFillFragment>(F); assert(FF.getValueSize() && "Invalid virtual align in concrete fragment!"); @@ -455,12 +482,6 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, break; } - case MCFragment::FT_Inst: { - MCInstFragment &IF = cast<MCInstFragment>(F); - OW->WriteBytes(StringRef(IF.getCode().begin(), IF.getCode().size())); - break; - } - case MCFragment::FT_LEB: { MCLEBFragment &LF = cast<MCLEBFragment>(F); OW->WriteBytes(LF.getContents().str()); @@ -468,6 +489,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, } case MCFragment::FT_Org: { + ++stats::EmittedOrgFragments; MCOrgFragment &OF = cast<MCOrgFragment>(F); for (uint64_t i = 0, e = FragmentSize; i != e; ++i) @@ -534,9 +556,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)); @@ -613,24 +635,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<MCDataFragment>(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<MCInstFragment>(it2); - if (IF) { - for (MCInstFragment::fixup_iterator it3 = IF->fixup_begin(), - ie3 = IF->fixup_end(); it3 != ie3; ++it3) { + MCEncodedFragment *F = dyn_cast<MCEncodedFragment>(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); } } } @@ -666,7 +678,7 @@ bool MCAssembler::fragmentNeedsRelaxation(const MCInstFragment *IF, return false; for (MCInstFragment::const_fixup_iterator it = IF->fixup_begin(), - ie = IF->fixup_end(); it != ie; ++it) + ie = IF->fixup_end(); it != ie; ++it) if (fixupNeedsRelaxation(*it, IF, Layout)) return true; @@ -700,11 +712,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; } @@ -758,39 +767,39 @@ bool MCAssembler::relaxDwarfCallFrameFragment(MCAsmLayout &Layout, return OldSize != Data.size(); } -bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, - MCSectionData &SD) { +bool MCAssembler::layoutSectionOnce(MCAsmLayout &Layout, MCSectionData &SD) { + // Holds the first fragment which needed relaxing during this layout. It will + // remain NULL if none were relaxed. MCFragment *FirstInvalidFragment = NULL; + // Scan for fragments that need relaxation. - for (MCSectionData::iterator it2 = SD.begin(), - ie2 = SD.end(); it2 != ie2; ++it2) { - // Check if this is an fragment that needs relaxation. - bool relaxedFrag = false; - switch(it2->getKind()) { + for (MCSectionData::iterator I = SD.begin(), IE = SD.end(); I != IE; ++I) { + // Check if this is a fragment that needs relaxation. + bool RelaxedFrag = false; + switch(I->getKind()) { default: - break; + break; case MCFragment::FT_Inst: - relaxedFrag = relaxInstruction(Layout, *cast<MCInstFragment>(it2)); + RelaxedFrag = relaxInstruction(Layout, *cast<MCInstFragment>(I)); break; case MCFragment::FT_Dwarf: - relaxedFrag = relaxDwarfLineAddr(Layout, - *cast<MCDwarfLineAddrFragment>(it2)); + RelaxedFrag = relaxDwarfLineAddr(Layout, + *cast<MCDwarfLineAddrFragment>(I)); break; case MCFragment::FT_DwarfFrame: - relaxedFrag = + RelaxedFrag = relaxDwarfCallFrameFragment(Layout, - *cast<MCDwarfCallFrameFragment>(it2)); + *cast<MCDwarfCallFrameFragment>(I)); break; case MCFragment::FT_LEB: - relaxedFrag = relaxLEB(Layout, *cast<MCLEBFragment>(it2)); + RelaxedFrag = relaxLEB(Layout, *cast<MCLEBFragment>(I)); break; } - // Update the layout, and remember that we relaxed. - if (relaxedFrag && !FirstInvalidFragment) - FirstInvalidFragment = it2; + if (RelaxedFrag && !FirstInvalidFragment) + FirstInvalidFragment = I; } if (FirstInvalidFragment) { - Layout.Invalidate(FirstInvalidFragment); + Layout.invalidateFragmentsAfter(FirstInvalidFragment); return true; } return false; @@ -802,7 +811,7 @@ bool MCAssembler::layoutOnce(MCAsmLayout &Layout) { bool WasRelaxed = false; for (iterator it = begin(), ie = end(); it != ie; ++it) { MCSectionData &SD = *it; - while(layoutSectionOnce(Layout, SD)) + while (layoutSectionOnce(Layout, SD)) WasRelaxed = true; } @@ -870,7 +879,7 @@ void MCFragment::dump() { } OS << "] (" << Contents.size() << " bytes)"; - if (!DF->getFixups().empty()) { + if (DF->fixup_begin() != DF->fixup_end()) { OS << ",\n "; OS << " Fixups:["; for (MCDataFragment::const_fixup_iterator it = DF->fixup_begin(), @@ -973,6 +982,7 @@ void MCAssembler::dump() { #endif // anchors for MC*Fragment vtables +void MCEncodedFragment::anchor() { } void MCDataFragment::anchor() { } void MCInstFragment::anchor() { } void MCAlignFragment::anchor() { } |