diff options
author | Pete Cooper <peter_cooper@apple.com> | 2015-06-17 22:01:28 +0000 |
---|---|---|
committer | Pete Cooper <peter_cooper@apple.com> | 2015-06-17 22:01:28 +0000 |
commit | e0d4037c6a0bcbdadf080e7a2ccd9846370d5f4c (patch) | |
tree | 8f06a28bad1808f1bfb648bb2c2a0e956d660231 /llvm/lib | |
parent | 6cac62797fbb1462cbe9ec3fccf94b7ecc6847e0 (diff) | |
download | bcm5719-llvm-e0d4037c6a0bcbdadf080e7a2ccd9846370d5f4c.tar.gz bcm5719-llvm-e0d4037c6a0bcbdadf080e7a2ccd9846370d5f4c.zip |
Devirtualize and pack MCFragment to reduce memory usage.
MCFragment didn't really need vtables. The majority of virtual methods were just getters and setters.
This removes the vtables and uses dispatch on the kind to do things like delete which needs to
get the appropriate class.
This reduces memory on the verify use list order test case by about 2MB out of 800MB.
Reviewed by Rafael EspĂndola
llvm-svn: 239952
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/MCAssembler.cpp | 126 | ||||
-rw-r--r-- | llvm/lib/MC/MCELFStreamer.cpp | 2 |
2 files changed, 79 insertions, 49 deletions
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()) { |