aboutsummaryrefslogtreecommitdiff
path: root/lib/MC/MCAssembler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MC/MCAssembler.cpp')
-rw-r--r--lib/MC/MCAssembler.cpp148
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() { }