1 //===- llvm-extract.cpp - LLVM function extraction utility ----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file was developed by the LLVM research group and is distributed under 6 // the University of Illinois Open Source License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This utility changes the input module to only contain a single function, 11 // which is primarily used for debugging transformations. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm/Module.h" 16 #include "llvm/PassManager.h" 17 #include "llvm/Bytecode/Reader.h" 18 #include "llvm/Bytecode/WriteBytecodePass.h" 19 #include "llvm/Transforms/IPO.h" 20 #include "llvm/Target/TargetData.h" 21 #include "llvm/Support/CommandLine.h" 22 #include "llvm/Support/ManagedStatic.h" 23 #include "llvm/Support/Streams.h" 24 #include "llvm/System/Signals.h" 25 #include <iostream> 26 #include <memory> 27 #include <fstream> 28 using namespace llvm; 29 30 // InputFilename - The filename to read from. 31 static cl::opt<std::string> 32 InputFilename(cl::Positional, cl::desc("<input bytecode file>"), 33 cl::init("-"), cl::value_desc("filename")); 34 35 static cl::opt<std::string> 36 OutputFilename("o", cl::desc("Specify output filename"), 37 cl::value_desc("filename"), cl::init("-")); 38 39 static cl::opt<bool> 40 Force("f", cl::desc("Overwrite output files")); 41 42 static cl::opt<bool> 43 DeleteFn("delete", cl::desc("Delete specified function from Module")); 44 45 // ExtractFunc - The function to extract from the module... defaults to main. 46 static cl::opt<std::string> 47 ExtractFunc("func", cl::desc("Specify function to extract"), cl::init("main"), 48 cl::value_desc("function")); 49 50 int main(int argc, char **argv) { 51 llvm_shutdown_obj X; // Call llvm_shutdown() on exit. 52 try { 53 cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n"); 54 sys::PrintStackTraceOnErrorSignal(); 55 56 std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); 57 if (M.get() == 0) { 58 cerr << argv[0] << ": bytecode didn't read correctly.\n"; 59 return 1; 60 } 61 62 // Figure out which function we should extract 63 Function *F = M.get()->getNamedFunction(ExtractFunc); 64 if (F == 0) { 65 cerr << argv[0] << ": program doesn't contain function named '" 66 << ExtractFunc << "'!\n"; 67 return 1; 68 } 69 70 // In addition to deleting all other functions, we also want to spiff it 71 // up a little bit. Do this now. 72 PassManager Passes; 73 Passes.add(new TargetData(M.get())); // Use correct TargetData 74 // Either isolate the function or delete it from the Module 75 Passes.add(createFunctionExtractionPass(F, DeleteFn)); 76 Passes.add(createGlobalDCEPass()); // Delete unreachable globals 77 Passes.add(createFunctionResolvingPass()); // Delete prototypes 78 Passes.add(createDeadTypeEliminationPass()); // Remove dead types... 79 80 std::ostream *Out = 0; 81 82 if (OutputFilename != "-") { // Not stdout? 83 if (!Force && std::ifstream(OutputFilename.c_str())) { 84 // If force is not specified, make sure not to overwrite a file! 85 cerr << argv[0] << ": error opening '" << OutputFilename 86 << "': file exists!\n" 87 << "Use -f command line argument to force output\n"; 88 return 1; 89 } 90 std::ios::openmode io_mode = std::ios::out | std::ios::trunc | 91 std::ios::binary; 92 Out = new std::ofstream(OutputFilename.c_str(), io_mode); 93 } else { // Specified stdout 94 // FIXME: cout is not binary! 95 Out = &std::cout; 96 } 97 98 OStream L(*Out); 99 Passes.add(new WriteBytecodePass(&L)); // Write bytecode to file... 100 Passes.run(*M.get()); 101 102 if (Out != &std::cout) 103 delete Out; 104 return 0; 105 } catch (const std::string& msg) { 106 cerr << argv[0] << ": " << msg << "\n"; 107 } catch (...) { 108 cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; 109 } 110 return 1; 111 } 112