aboutsummaryrefslogtreecommitdiffstats
path: root/lib/MC
diff options
context:
space:
mode:
authorEli Bendersky <eliben@google.com>2013-01-15 23:22:09 +0000
committerEli Bendersky <eliben@google.com>2013-01-15 23:22:09 +0000
commit9ccb76998f741a7d3f0f217392a783dfb99c6e87 (patch)
tree4f87f004af99d84cd1e61b3fbb2b5814441feba0 /lib/MC
parent1c99a7f4892a24eb227802e042917d05d8cd415f (diff)
downloadexternal_llvm-9ccb76998f741a7d3f0f217392a783dfb99c6e87.zip
external_llvm-9ccb76998f741a7d3f0f217392a783dfb99c6e87.tar.gz
external_llvm-9ccb76998f741a7d3f0f217392a783dfb99c6e87.tar.bz2
Optimize the memory usage of MC bundling, by creating a new type of fragment
into which we can emit single instructions without fixups (which is most instructions). This is an optimization required because MCDataFragment is prety large (240 bytes on x64), with no change in functionality. For large programs, this reduces memory usage overhead required for bundling by 40%. To make the code as palatable as possible, the MCEncodedFragment interface was further fragmented (no pun intended) and MCEncodedFragmentWithFixups is used as the interface to work against when the user expects fixups. MCDataFragment and MCRelaxableFragment implement this interface, while the new MCCompactEncodedInstFragment implements MCEncodeFragment. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172572 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC')
-rw-r--r--lib/MC/MCAssembler.cpp36
-rw-r--r--lib/MC/MCELFStreamer.cpp14
2 files changed, 46 insertions, 4 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 5fdc57a..c51ddc8 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -38,6 +38,8 @@ STATISTIC(EmittedRelaxableFragments,
"Number of emitted assembler fragments - relaxable");
STATISTIC(EmittedDataFragments,
"Number of emitted assembler fragments - data");
+STATISTIC(EmittedCompactEncodedInstFragments,
+ "Number of emitted assembler fragments - compact encoded inst");
STATISTIC(EmittedAlignFragments,
"Number of emitted assembler fragments - align");
STATISTIC(EmittedFillFragments,
@@ -222,6 +224,11 @@ MCEncodedFragment::~MCEncodedFragment() {
/* *** */
+MCEncodedFragmentWithFixups::~MCEncodedFragmentWithFixups() {
+}
+
+/* *** */
+
MCSectionData::MCSectionData() : Section(0) {}
MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A)
@@ -388,6 +395,7 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
switch (F.getKind()) {
case MCFragment::FT_Data:
case MCFragment::FT_Relaxable:
+ case MCFragment::FT_CompactEncodedInst:
return cast<MCEncodedFragment>(F).getContents().size();
case MCFragment::FT_Fill:
return cast<MCFillFragment>(F).getSize();
@@ -570,6 +578,11 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
writeFragmentContents(F, OW);
break;
+ case MCFragment::FT_CompactEncodedInst:
+ ++stats::EmittedCompactEncodedInstFragments;
+ writeFragmentContents(F, OW);
+ break;
+
case MCFragment::FT_Fill: {
++stats::EmittedFillFragments;
MCFillFragment &FF = cast<MCFillFragment>(F);
@@ -742,9 +755,10 @@ 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) {
- MCEncodedFragment *F = dyn_cast<MCEncodedFragment>(it2);
+ MCEncodedFragmentWithFixups *F =
+ dyn_cast<MCEncodedFragmentWithFixups>(it2);
if (F) {
- for (MCEncodedFragment::fixup_iterator it3 = F->fixup_begin(),
+ for (MCEncodedFragmentWithFixups::fixup_iterator it3 = F->fixup_begin(),
ie3 = F->fixup_end(); it3 != ie3; ++it3) {
MCFixup &Fixup = *it3;
uint64_t FixedValue = handleFixup(Layout, *F, Fixup);
@@ -954,6 +968,8 @@ void MCFragment::dump() {
switch (getKind()) {
case MCFragment::FT_Align: OS << "MCAlignFragment"; break;
case MCFragment::FT_Data: OS << "MCDataFragment"; break;
+ case MCFragment::FT_CompactEncodedInst:
+ OS << "MCCompactEncodedInstFragment"; break;
case MCFragment::FT_Fill: OS << "MCFillFragment"; break;
case MCFragment::FT_Relaxable: OS << "MCRelaxableFragment"; break;
case MCFragment::FT_Org: OS << "MCOrgFragment"; break;
@@ -1001,6 +1017,19 @@ void MCFragment::dump() {
}
break;
}
+ case MCFragment::FT_CompactEncodedInst: {
+ const MCCompactEncodedInstFragment *CEIF =
+ cast<MCCompactEncodedInstFragment>(this);
+ OS << "\n ";
+ OS << " Contents:[";
+ const SmallVectorImpl<char> &Contents = CEIF->getContents();
+ for (unsigned i = 0, e = Contents.size(); i != e; ++i) {
+ if (i) OS << ",";
+ OS << hexdigit((Contents[i] >> 4) & 0xF) << hexdigit(Contents[i] & 0xF);
+ }
+ OS << "] (" << Contents.size() << " bytes)";
+ break;
+ }
case MCFragment::FT_Fill: {
const MCFillFragment *FF = cast<MCFillFragment>(this);
OS << " Value:" << FF->getValue() << " ValueSize:" << FF->getValueSize()
@@ -1094,7 +1123,9 @@ void MCAssembler::dump() {
// 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() { }
@@ -1102,3 +1133,4 @@ void MCOrgFragment::anchor() { }
void MCLEBFragment::anchor() { }
void MCDwarfLineAddrFragment::anchor() { }
void MCDwarfCallFrameFragment::anchor() { }
+
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index cae73be..e5b749e 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -371,8 +371,10 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
// data fragment).
//
// If bundling is enabled:
- // - If we're not in a bundle-locked group, emit the instruction into a data
- // fragment of its own.
+ // - If we're not in a bundle-locked group, emit the instruction into a
+ // fragment of its own. If there are no fixups registered for the
+ // instruction, emit a MCCompactEncodedInstFragment. Otherwise, emit a
+ // MCDataFragment.
// - If we're in a bundle-locked group, append the instruction to the current
// data fragment because we want all the instructions in a group to get into
// the same fragment. Be careful not to do that for the first instruction in
@@ -383,6 +385,14 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
MCSectionData *SD = getCurrentSectionData();
if (SD->isBundleLocked() && !SD->isBundleGroupBeforeFirstInst())
DF = getOrCreateDataFragment();
+ else if (!SD->isBundleLocked() && Fixups.size() == 0) {
+ // Optimize memory usage by emitting the instruction to a
+ // MCCompactEncodedInstFragment when not in a bundle-locked group and
+ // there are no fixups registered.
+ MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment(SD);
+ CEIF->getContents().append(Code.begin(), Code.end());
+ return;
+ }
else {
DF = new MCDataFragment(SD);
if (SD->getBundleLockState() == MCSectionData::BundleLockedAlignToEnd) {