From 8728e097dfbec3630a1dd907431c0f14274a1ae8 Mon Sep 17 00:00:00 2001 From: Nirav Dave Date: Fri, 27 Apr 2018 15:45:27 +0000 Subject: [PATCH] [MC] Allow MCAssembler to be constructed without all subcomponents. NFCI. llvm-svn: 331047 --- llvm/include/llvm/MC/MCAssembler.h | 23 ++++++++----- llvm/include/llvm/MC/MCObjectStreamer.h | 3 -- llvm/lib/MC/MCAssembler.cpp | 43 ++++++++++++++++++------- llvm/lib/MC/MCObjectStreamer.cpp | 8 ++--- 4 files changed, 50 insertions(+), 27 deletions(-) diff --git a/llvm/include/llvm/MC/MCAssembler.h b/llvm/include/llvm/MC/MCAssembler.h index b91b04414021..8ad4a611f7d4 100644 --- a/llvm/include/llvm/MC/MCAssembler.h +++ b/llvm/include/llvm/MC/MCAssembler.h @@ -99,11 +99,11 @@ public: private: MCContext &Context; - MCAsmBackend &Backend; + std::unique_ptr Backend; - MCCodeEmitter &Emitter; + std::unique_ptr Emitter; - MCObjectWriter &Writer; + std::unique_ptr Writer; SectionListType Sections; @@ -214,8 +214,9 @@ public: // concrete and require clients to pass in a target like object. The other // option is to make this abstract, and have targets provide concrete // implementations as we do with AsmParser. - MCAssembler(MCContext &Context, MCAsmBackend &Backend, - MCCodeEmitter &Emitter, MCObjectWriter &Writer); + MCAssembler(MCContext &Context, std::unique_ptr Backend, + std::unique_ptr Emitter, + std::unique_ptr Writer); MCAssembler(const MCAssembler &) = delete; MCAssembler &operator=(const MCAssembler &) = delete; ~MCAssembler(); @@ -274,11 +275,17 @@ public: MCContext &getContext() const { return Context; } - MCAsmBackend &getBackend() const { return Backend; } + MCAsmBackend *getBackendPtr() const { return Backend.get(); } - MCCodeEmitter &getEmitter() const { return Emitter; } + MCCodeEmitter *getEmitterPtr() const { return Emitter.get(); } - MCObjectWriter &getWriter() const { return Writer; } + MCObjectWriter *getWriterPtr() const { return Writer.get(); } + + MCAsmBackend &getBackend() const { return *Backend; } + + MCCodeEmitter &getEmitter() const { return *Emitter; } + + MCObjectWriter &getWriter() const { return *Writer; } MCDwarfLineTableParams getDWARFLinetableParams() const { return LTParams; } void setDWARFLinetableParams(MCDwarfLineTableParams P) { LTParams = P; } diff --git a/llvm/include/llvm/MC/MCObjectStreamer.h b/llvm/include/llvm/MC/MCObjectStreamer.h index 8e9b4ac56320..55556d7ec3cf 100644 --- a/llvm/include/llvm/MC/MCObjectStreamer.h +++ b/llvm/include/llvm/MC/MCObjectStreamer.h @@ -34,9 +34,6 @@ class raw_pwrite_stream; /// to that file format or custom semantics expected by the object writer /// implementation. class MCObjectStreamer : public MCStreamer { - std::unique_ptr ObjectWriter; - std::unique_ptr TAB; - std::unique_ptr Emitter; std::unique_ptr Assembler; MCSection::iterator CurInsertionPoint; bool EmitEHFrame; diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index a0f9a857e3ce..721a2a62f527 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -83,9 +83,12 @@ STATISTIC(PaddingFragmentsBytes, /* *** */ -MCAssembler::MCAssembler(MCContext &Context, MCAsmBackend &Backend, - MCCodeEmitter &Emitter, MCObjectWriter &Writer) - : Context(Context), Backend(Backend), Emitter(Emitter), Writer(Writer), +MCAssembler::MCAssembler(MCContext &Context, + std::unique_ptr Backend, + std::unique_ptr Emitter, + std::unique_ptr Writer) + : Context(Context), Backend(std::move(Backend)), + Emitter(std::move(Emitter)), Writer(std::move(Writer)), BundleAlignSize(0), RelaxAll(false), SubsectionsViaSymbols(false), IncrementalLinkerCompatible(false), ELFHeaderEFlags(0) { VersionInfo.Major = 0; // Major version == 0 for "none specified" @@ -110,9 +113,12 @@ void MCAssembler::reset() { VersionInfo.Major = 0; // reset objects owned by us - getBackend().reset(); - getEmitter().reset(); - getWriter().reset(); + if (getBackendPtr()) + getBackendPtr()->reset(); + if (getEmitterPtr()) + getEmitterPtr()->reset(); + if (getWriterPtr()) + getWriterPtr()->reset(); getLOHContainer().reset(); } @@ -215,8 +221,9 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, } } - bool IsPCRel = Backend.getFixupKindInfo( - Fixup.getKind()).Flags & MCFixupKindInfo::FKF_IsPCRel; + assert(getBackendPtr() && "Expected assembler backend"); + bool IsPCRel = getBackendPtr()->getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsPCRel; bool IsResolved; if (IsPCRel) { @@ -251,8 +258,8 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, Value -= Layout.getSymbolOffset(Sym); } - bool ShouldAlignPC = Backend.getFixupKindInfo(Fixup.getKind()).Flags & - MCFixupKindInfo::FKF_IsAlignedDownTo32Bits; + bool ShouldAlignPC = getBackend().getFixupKindInfo(Fixup.getKind()).Flags & + MCFixupKindInfo::FKF_IsAlignedDownTo32Bits; assert((ShouldAlignPC ? IsPCRel : true) && "FKF_IsAlignedDownTo32Bits is only allowed on PC-relative fixups!"); @@ -266,7 +273,7 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, } // Let the backend force a relocation if needed. - if (IsResolved && Backend.shouldForceRelocation(*this, Fixup, Target)) + if (IsResolved && getBackend().shouldForceRelocation(*this, Fixup, Target)) IsResolved = false; return IsResolved; @@ -274,6 +281,7 @@ bool MCAssembler::evaluateFixup(const MCAsmLayout &Layout, uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout, const MCFragment &F) const { + assert(getBackendPtr() && "Requires assembler backend"); switch (F.getKind()) { case MCFragment::FT_Data: return cast(F).getContents().size(); @@ -437,6 +445,7 @@ void MCAssembler::registerSymbol(const MCSymbol &Symbol, bool *Created) { void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize, MCObjectWriter *OW) const { + assert(getBackendPtr() && "Expected assembler backend"); // Should NOP padding be written out before this fragment? unsigned BundlePadding = F.getBundlePadding(); if (BundlePadding > 0) { @@ -470,7 +479,8 @@ void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize, /// \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(); + MCObjectWriter *OW = Asm.getWriterPtr(); + assert(OW && "Need ObjectWriter to write fragment"); // FIXME: Embed in fragments instead? uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F); @@ -619,6 +629,8 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, void MCAssembler::writeSectionData(const MCSection *Sec, const MCAsmLayout &Layout) const { + assert(getBackendPtr() && "Expected assembler backend"); + // Ignore virtual sections. if (Sec->isVirtualSection()) { assert(Layout.getSectionFileSize(Sec) == 0 && "Invalid size for section!"); @@ -688,6 +700,7 @@ MCAssembler::handleFixup(const MCAsmLayout &Layout, MCFragment &F, } void MCAssembler::layout(MCAsmLayout &Layout) { + assert(getBackendPtr() && "Expected assembler backend"); DEBUG_WITH_TYPE("mc-dump", { errs() << "assembler backend - pre-layout\n--\n"; dump(); }); @@ -788,6 +801,7 @@ void MCAssembler::Finish() { bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup, const MCRelaxableFragment *DF, const MCAsmLayout &Layout) const { + assert(getBackendPtr() && "Expected assembler backend"); MCValue Target; uint64_t Value; bool Resolved = evaluateFixup(Layout, Fixup, DF, Target, Value); @@ -801,6 +815,7 @@ bool MCAssembler::fixupNeedsRelaxation(const MCFixup &Fixup, bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F, const MCAsmLayout &Layout) const { + assert(getBackendPtr() && "Expected assembler backend"); // If this inst doesn't ever need relaxation, ignore it. This occurs when we // are intentionally pushing out inst fragments, or because we relaxed a // previous instruction to one that doesn't need relaxation. @@ -816,6 +831,8 @@ bool MCAssembler::fragmentNeedsRelaxation(const MCRelaxableFragment *F, bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, MCRelaxableFragment &F) { + assert(getEmitterPtr() && + "Expected CodeEmitter defined for relaxInstruction"); if (!fragmentNeedsRelaxation(&F, Layout)) return false; @@ -848,6 +865,7 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, bool MCAssembler::relaxPaddingFragment(MCAsmLayout &Layout, MCPaddingFragment &PF) { + assert(getBackendPtr() && "Expected assembler backend"); uint64_t OldSize = PF.getSize(); if (!getBackend().relaxFragment(&PF, Layout)) return false; @@ -992,6 +1010,7 @@ bool MCAssembler::layoutOnce(MCAsmLayout &Layout) { } void MCAssembler::finishLayout(MCAsmLayout &Layout) { + assert(getBackendPtr() && "Expected assembler backend"); // The layout is done. Mark every fragment as valid. for (unsigned int i = 0, n = Layout.getSectionOrder().size(); i != n; ++i) { MCSection &Section = *Layout.getSectionOrder()[i]; diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 316a3be8d89f..19c41df473ce 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -27,10 +27,10 @@ MCObjectStreamer::MCObjectStreamer(MCContext &Context, std::unique_ptr TAB, raw_pwrite_stream &OS, std::unique_ptr Emitter) - : MCStreamer(Context), ObjectWriter(TAB->createObjectWriter(OS)), - TAB(std::move(TAB)), Emitter(std::move(Emitter)), - Assembler(llvm::make_unique(Context, *this->TAB, - *this->Emitter, *ObjectWriter)), + : MCStreamer(Context), + Assembler(llvm::make_unique(Context, std::move(TAB), + std::move(Emitter), + TAB->createObjectWriter(OS))), EmitEHFrame(true), EmitDebugFrame(false) {} MCObjectStreamer::~MCObjectStreamer() {}