Files
revng-revng/tools/pipeline/pipe/Main.cpp
2024-08-05 17:41:34 +02:00

131 lines
4.6 KiB
C++

// \file Main.cpp
//
// This file is distributed under the MIT License. See LICENSE.md for details.
//
#include <iostream>
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/raw_os_ostream.h"
#include "revng/Model/LoadModelPass.h"
#include "revng/Pipeline/AllRegistries.h"
#include "revng/Pipeline/ContainerSet.h"
#include "revng/Pipeline/CopyPipe.h"
#include "revng/Pipeline/GenericLLVMPipe.h"
#include "revng/Pipeline/LLVMContainerFactory.h"
#include "revng/Pipeline/LLVMKind.h"
#include "revng/Pipeline/Loader.h"
#include "revng/Pipeline/Target.h"
#include "revng/Pipes/ModelGlobal.h"
#include "revng/Pipes/PipelineManager.h"
#include "revng/Support/InitRevng.h"
using std::string;
using namespace llvm;
using namespace llvm::cl;
using namespace pipeline;
using namespace ::revng::pipes;
using namespace ::revng;
static cl::list<string> Arguments(Positional,
ZeroOrMore,
desc("<pipe> <containers>..."),
cat(MainCategory));
static llvm::cl::list<std::string>
InputPipeline("P", llvm::cl::desc("<Pipeline>"), llvm::cl::cat(MainCategory));
static llvm::cl::list<std::string> EnablingFlags("f",
llvm::cl::desc("list of "
"pipeline "
"enabling "
"flags"),
llvm::cl::cat(MainCategory));
static llvm::cl::alias A1("l",
llvm::cl::desc("Alias for --load"),
llvm::cl::aliasopt(llvm::LoadOpt),
llvm::cl::cat(MainCategory));
static ExitOnError AbortOnError;
int main(int argc, char *argv[]) {
using revng::FilePath;
revng::InitRevng X(argc, argv, "", { &MainCategory });
Registry::runAllInitializationRoutines();
auto
Manager = AbortOnError(revng::pipes::PipelineManager::create(InputPipeline,
EnablingFlags,
""));
const pipeline::Loader &Loader = Manager.getLoader();
const llvm::StringMap<PipeWrapper> &PipesMap = Loader.getPipes();
if (Arguments.size() <= 1 or PipesMap.count(Arguments[0]) == 0) {
llvm::outs() << "USAGE: revng-pipe [options] <pipe> <model> <args>...\n\n";
llvm::outs() << "<pipe> can be one of:\n\n";
for (auto &Pair : PipesMap) {
llvm::outs() << "revng pipe " << Pair.first() << " <model> ";
for (size_t I = 0; I < Pair.second.Pipe->getContainerArgumentsCount();
I++) {
llvm::outs() << "<" << Pair.second.Pipe->getContainerName(I) << "> ";
}
llvm::outs() << "\n";
}
return EXIT_SUCCESS;
}
const auto &Name = ModelGlobalName;
auto *Model(cantFail(Manager.context().getGlobal<ModelGlobal>(Name)));
InputPath = Arguments[1];
AbortOnError(Model->load(FilePath::fromLocalStorage(Arguments[1])));
const auto &Pipe = PipesMap.find(Arguments[0])->second.Pipe;
std::vector<std::string> DefaultNames;
pipeline::ContainerSet Set;
if (Arguments.size() - 2 != Pipe->getContainerArgumentsCount()) {
llvm::errs() << "Pipe " << Arguments[0] << " required "
<< Pipe->getContainerArgumentsCount() << " arguments\n";
return EXIT_FAILURE;
}
for (size_t I = 0; I < Pipe->getContainerArgumentsCount(); I++) {
DefaultNames.push_back((llvm::Twine("arg") + llvm::Twine(I)).str());
}
PipeWrapper ClonedPipe(Pipe, DefaultNames);
for (size_t I = 0; I < Pipe->getContainerArgumentsCount(); I++) {
llvm::StringRef Name = ClonedPipe.Pipe->getContainerName(I);
auto &Factory = Loader.getContainerFactory(Name);
Set.add(DefaultNames[I], Factory, Factory(DefaultNames[I]));
AbortOnError(Set.at(DefaultNames[I])
.load(FilePath::fromLocalStorage(Arguments[I + 2])));
}
auto Enumeration = Set.enumerate();
ExecutionContext ExecutionContext(Manager.context(),
&ClonedPipe,
Enumeration);
AbortOnError(ClonedPipe.Pipe->run(ExecutionContext, Set));
for (size_t I = 0; I < Pipe->getContainerArgumentsCount(); I++) {
if (not Pipe->isContainerArgumentConst(I))
AbortOnError(Set.at(DefaultNames[I])
.store(FilePath::fromLocalStorage(Arguments[I + 2])));
}
return EXIT_SUCCESS;
}