/// \file Main.cpp // // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "llvm/Support/CommandLine.h" #include "llvm/Support/MemoryBuffer.h" #include "revng/EarlyFunctionAnalysis/FunctionMetadataCache.h" #include "revng/Model/ToolHelpers.h" #include "revng/Support/IRHelpers.h" #include "revng/Support/InitRevng.h" #include "./DecoratedFunction.h" using namespace llvm; static cl::opt InputModule(cl::Positional, cl::cat(MainCategory), cl::desc(""), cl::init("-"), cl::value_desc("filename")); static cl::opt OutputFilename("o", cl::cat(MainCategory), cl::init("-"), llvm::cl::desc(""), cl::value_desc("filename")); int main(int argc, const char **argv) { revng::InitRevng X(argc, argv); cl::HideUnrelatedOptions({ &MainCategory }); cl::ParseCommandLineOptions(argc, argv); auto BufOrError = MemoryBuffer::getFileOrSTDIN(InputModule); if (std::error_code EC = BufOrError.getError()) ExitOnError("Unable to read LLVM IR module: " + EC.message() + "\n"); SMDiagnostic Diagnostic; LLVMContext Context; auto Module = llvm::parseIR(*BufOrError.get(), Diagnostic, Context); TupleTree Model; if (hasModel(*Module)) Model = loadModel(*Module); else ExitOnError("Unable to extract model\n"); SortedVector DecoratedFunctions; auto *RootFunction = Module->getFunction("root"); revng_assert(RootFunction != nullptr); FunctionMetadataCache Cache; if (not RootFunction->isDeclaration()) { for (BasicBlock &BB : *Module->getFunction("root")) { llvm::Instruction *Term = BB.getTerminator(); auto *FMMDNode = Term->getMetadata(FunctionMetadataMDName); if (not FMMDNode) continue; const efa::FunctionMetadata &FM = Cache.getFunctionMetadata(&BB); auto &Function = Model->Functions().at(FM.Entry()); revng::DecoratedFunction NewFunction(FM.Entry(), Function.OriginalName(), FM, Function.Attributes()); DecoratedFunctions.insert(std::move(NewFunction)); } } for (Function &F : FunctionTags::Isolated.functions(Module.get())) { auto *FMMDNode = F.getMetadata(FunctionMetadataMDName); const efa::FunctionMetadata &FM = Cache.getFunctionMetadata(&F); if (not FMMDNode or DecoratedFunctions.count(FM.Entry()) != 0) continue; auto &Function = Model->Functions().at(FM.Entry()); revng::DecoratedFunction NewFunction(FM.Entry(), Function.OriginalName(), FM, Function.Attributes()); DecoratedFunctions.insert(std::move(NewFunction)); } ExitOnError AbortOnError; AbortOnError((serializeToFile(DecoratedFunctions, OutputFilename))); return EXIT_SUCCESS; }