#pragma once // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "llvm/IR/PassManager.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "revng/Model/Binary.h" #include "revng/TupleTree/TupleTree.h" extern llvm::cl::opt ModelPath; inline const char *ModelMetadataName = "revng.model"; TupleTree loadModel(const llvm::Module &M); bool hasModel(const llvm::Module &M); class ModelWrapper { private: using ModelPointer = std::variant *, const TupleTree *>; private: ModelPointer TheBinary; bool HasChanged = false; public: ModelWrapper(TupleTree &TheBinary) : TheBinary(&TheBinary) {} ModelWrapper(const TupleTree &TheBinary) : TheBinary(&TheBinary) {} public: static ModelWrapper createConst(const TupleTree &TheBinary) { return ModelWrapper(TheBinary); } public: const TupleTree &getReadOnlyModel() const; TupleTree &getWriteableModel(); bool hasChanged() const { return HasChanged; } template bool invalidate(IRUnitT &, const PreservedAnalysesT &, InvalidatorT &) { return false; } }; class LoadModelWrapperPass : public llvm::ImmutablePass { public: static char ID; private: ModelWrapper Wrapper; public: LoadModelWrapperPass(const ModelWrapper &Wrapper) : llvm::ImmutablePass(ID), Wrapper(Wrapper) {} public: bool doInitialization(llvm::Module &M) override final; bool doFinalization(llvm::Module &M) override final; public: ModelWrapper &get() { return Wrapper; } }; class LoadModelAnalysis : public llvm::AnalysisInfoMixin { friend llvm::AnalysisInfoMixin; private: static llvm::AnalysisKey Key; public: using Result = ModelWrapper; private: ModelWrapper Wrapper; private: LoadModelAnalysis(const ModelWrapper &Wrapper) : Wrapper(Wrapper) {} public: static LoadModelAnalysis fromModelWrapper(const ModelWrapper &Wrapper) { return { Wrapper }; } public: ModelWrapper run(llvm::Module &M, llvm::ModuleAnalysisManager &); ModelWrapper run(llvm::Function &F, llvm::FunctionAnalysisManager &); };