// // This file is distributed under the MIT License. See LICENSE.md for details. // #include "revng/PipeboxCommon/Helpers/Native/Registry.h" #include "revng/PipeboxCommon/TraceRunner/Runner.h" #include "revng/PipeboxCommon/TraceRunner/Savepoint.h" using namespace revng::pypeline::helpers::native; using namespace revng::pypeline::tracerunner; using ContainerMap = llvm::StringMap>; static std::vector toPointerVector(const std::vector &Vec) { std::vector Result; for (auto &Element : Vec) Result.push_back(&Element); return Result; } static llvm::ArrayRef toArrayRef(const std::vector &Vec) { if (Vec.size() == 0) return {}; const ObjectID *Start = &*Vec.begin(); return { Start, Vec.size() }; } static void runTask(RegistryImpl &R, ContainerMap &CMap, const Model &TheModel, const PipeTask &Task) { revng_assert(R.Pipes.count(Task.Name) == 1); std::unique_ptr ThePipe = R.Pipes[Task.Name](Task.StaticConfig); std::vector Containers; revng::pypeline::Request Incoming; revng::pypeline::Request Outgoing; for (const PipeArgs &Arg : Task.Args) { std::vector IncomingChunk = toPointerVector(Arg.Incoming); std::vector OutgoingChunk = toPointerVector(Arg.Outgoing); Containers.push_back(&*CMap[Arg.Name]); Incoming.push_back(IncomingChunk); Outgoing.push_back(OutgoingChunk); } ThePipe->run(TheModel, Containers, Incoming, Outgoing, Task.DynamicConfig); } static void runTask(RegistryImpl &R, ContainerMap &CMap, Model &TheModel, const AnalysisTask &Task) { revng_assert(R.Analyses.count(Task.Name) == 1); std::unique_ptr TheAnalysis = R.Analyses[Task.Name](); std::vector Containers; revng::pypeline::Request Incoming; for (const AnalysisArgs &Arg : Task.Args) { std::vector IncomingChunk = toPointerVector(Arg.Incoming); Containers.push_back(&*CMap[Arg.Name]); Incoming.push_back(IncomingChunk); } llvm::Error Err = TheAnalysis->run(TheModel, Containers, Incoming, Task.Config); revng_assert(not Err); } static void runTask(ContainerMap &CMap, SavePoint &SV, const SavePointTask &Task) { for (const SavePointContainer &SPContainer : Task.Containers) { Container &Cont = *CMap[SPContainer.Name]; SV.save(Cont, SPContainer.Name, Task.ID, SPContainer.ConfigurationHash, toArrayRef(SPContainer.Incoming)); SV.load(Cont, SPContainer.Name, Task.ID, SPContainer.ConfigurationHash, toArrayRef(SPContainer.Outgoing)); } } void Runner::run(Model &TheModel, const TraceFile &File, SavePoint &SP) { ContainerMap Containers; for (const ContainerDeclaration &Decl : File.Containers) { revng_assert(Registry.Containers.count(Decl.Type) == 1); Containers[Decl.Name] = Registry.Containers[Decl.Type](); } for (const TaskDeclaration &Decl : File.Tasks) { if (std::holds_alternative(Decl)) { runTask(Registry, Containers, TheModel, std::get(Decl)); } else if (std::holds_alternative(Decl)) { runTask(Registry, Containers, TheModel, std::get(Decl)); } else if (std::holds_alternative(Decl)) { runTask(Containers, SP, std::get(Decl)); } else { revng_abort(); } } }