// // This file is distributed under the MIT License. See LICENSE.md for details. // #include "revng/CliftPipes/CliftContainer.h" #include "revng/CliftPipes/Clifter.h" #include "revng/Clifter/Clifter.h" #include "revng/Model/IRHelpers.h" #include "revng/Model/NameBuilder.h" #include "revng/Pipeline/RegisterPipe.h" #include "revng/Pipes/IRHelpers.h" namespace { class ClifterPipe { public: static constexpr auto Name = "clifter"; std::array getContract() const { using namespace pipeline; using namespace revng::kinds; return { ContractGroup({ Contract(StackAccessesSegregated, 0, CliftFunction, 1, InputPreservation::Preserve) }) }; } void run(pipeline::ExecutionContext &EC, const pipeline::LLVMContainer &LLVMContainer, revng::pipes::CliftFunctionContainer &CliftContainer) { CliftContainer.getContext()->loadDialect(); auto const &Model = *revng::getModelFromContext(EC); model::CNameBuilder NameBuilder(Model); const llvm::Module &M = LLVMContainer.getModule(); auto TargetToFunction = getTargetToFunctionMapping(M); // The importer construction itself only relies on minimal number of model // properties (e.g. architecture) to avoid creating dependencies for all // imported functions. The importer does some caching, but care is taken to // make sure that the pertinent model properties are queried within each // function import process regardless of caching. auto Importer = clift::Clifter::make(CliftContainer.getModule(), Model); for (const model::Function &Function : revng::getFunctionsAndCommit(EC, CliftContainer.name())) { auto It = TargetToFunction.find(Function.Entry()); revng_assert(It != TargetToFunction.end()); Importer->import(It->second); } } }; static pipeline::RegisterPipe X; } // namespace namespace revng::pypeline::piperuns { Clifter::Clifter(const class Model &Model, llvm::StringRef Config, llvm::StringRef DynamicConfig, const LLVMFunctionContainer &Input, CliftFunctionContainer &Output) : Binary(*Model.get().get()), Input(Input), Output(Output) { } void Clifter::runOnFunction(const model::Function &Function) { ObjectID Object(Function.Entry()); const llvm::Module &Module = Input.getModule(Object); const llvm::Function &LLVMFunction = getUniqueIsolatedFunction(Module, Function.Entry()); mlir::MLIRContext *Context = Output.getContext(); auto ModuleOpObject = clift::makeModule(*Context); auto Importer = clift::Clifter::make(ModuleOpObject.get(), Binary); Importer->import(&LLVMFunction); Output.assign(Object, std::move(ModuleOpObject)); } } // namespace revng::pypeline::piperuns