#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include "revng/Pipeline/ContainerEnumerator.h" #include "revng/Pipeline/Pipe.h" #include "revng/Support/ModuleStatistics.h" inline Logger<> ModuleStatisticsLogger("module-statistics"); namespace pipeline { /// Creates a global variable in the provided module that holds a pointer to /// each other global object so that they can't be removed by the linker void makeGlobalObjectsArray(llvm::Module &Module, llvm::StringRef GlobalArrayName); class LLVMContainer : public EnumerableContainer { private: using LinkageRestoreMap = std::map; public: static const char ID; private: using ThisType = LLVMContainer; private: std::unique_ptr Module; public: inline static const llvm::StringRef MIMEType = "application/x.llvm.bc+zstd"; inline static const char *Name = "llvm-container"; LLVMContainer(llvm::StringRef Name, Context *Context, llvm::LLVMContext *LLVMContext) : EnumerableContainer(*Context, Name), Module(std::make_unique("revng.module", *LLVMContext)) {} LLVMContainer(llvm::StringRef Name, Context *Context, std::unique_ptr M) : EnumerableContainer(*Context, Name), Module(std::move(M)) {} public: template static PipeWrapper wrapLLVMPasses(std::string LLVMModuleName, LLVMPasses &&...P) { return PipeWrapper::make(GenericLLVMPipe(std::move(P)...), { std::move(LLVMModuleName) }); } public: const llvm::Module &getModule() const { return *Module; } llvm::Module &getModule() { return *Module; } public: std::unique_ptr cloneFiltered(const TargetsList &Targets) const final; llvm::Error extractOne(llvm::raw_ostream &OS, const Target &Target) const override; public: llvm::Error serialize(llvm::raw_ostream &OS) const final; llvm::Error deserializeImpl(const llvm::MemoryBuffer &Buffer) final; void clearImpl() final { Module = std::make_unique("revng.module", Module->getContext()); } private: void mergeBackImpl(ThisType &&OtherContainer) final; }; } // namespace pipeline