diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-10-04 20:28:12 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-10-04 20:28:12 +0000 |
commit | ce4942c67154008535160eec8b913fb008038b6b (patch) | |
tree | a80e1a407d28d61e22be5dd84b73c4cc51ade54a /gnu/llvm/tools/llvm-extract | |
parent | 92440caccb2098ea0dd638dc607065155340d940 (diff) |
Import LLVM 5.0.0 release including clang, lld and lldb.
Diffstat (limited to 'gnu/llvm/tools/llvm-extract')
-rw-r--r-- | gnu/llvm/tools/llvm-extract/llvm-extract.cpp | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/gnu/llvm/tools/llvm-extract/llvm-extract.cpp b/gnu/llvm/tools/llvm-extract/llvm-extract.cpp index aa1eda2f094..d868db7f78a 100644 --- a/gnu/llvm/tools/llvm-extract/llvm-extract.cpp +++ b/gnu/llvm/tools/llvm-extract/llvm-extract.cpp @@ -17,10 +17,11 @@ #include "llvm/Bitcode/BitcodeWriterPass.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IRReader/IRReader.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" @@ -50,6 +51,10 @@ Force("f", cl::desc("Enable binary output on terminals")); static cl::opt<bool> DeleteFn("delete", cl::desc("Delete specified Globals from Module")); +static cl::opt<bool> + Recursive("recursive", + cl::desc("Recursively extract all called functions")); + // ExtractFuncs - The functions to extract from the module. static cl::list<std::string> ExtractFuncs("func", cl::desc("Specify function to extract"), @@ -226,6 +231,34 @@ int main(int argc, char **argv) { // Use *argv instead of argv[0] to work around a wrong GCC warning. ExitOnError ExitOnErr(std::string(*argv) + ": error reading input: "); + if (Recursive) { + std::vector<llvm::Function *> Workqueue; + for (GlobalValue *GV : GVs) { + if (auto *F = dyn_cast<Function>(GV)) { + Workqueue.push_back(F); + } + } + while (!Workqueue.empty()) { + Function *F = &*Workqueue.back(); + Workqueue.pop_back(); + ExitOnErr(F->materialize()); + for (auto &BB : *F) { + for (auto &I : BB) { + auto *CI = dyn_cast<CallInst>(&I); + if (!CI) + continue; + Function *CF = CI->getCalledFunction(); + if (!CF) + continue; + if (CF->isDeclaration() || GVs.count(CF)) + continue; + GVs.insert(CF); + Workqueue.push_back(CF); + } + } + } + } + auto Materialize = [&](GlobalValue &GV) { ExitOnErr(GV.materialize()); }; // Materialize requisite global values. |