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/System/Signals.h" 23 #include <memory> 24 #include <fstream> 25 using namespace llvm; 26 27 // InputFilename - The filename to read from. 28 static cl::opt<std::string> 29 InputFilename(cl::Positional, cl::desc("<input bytecode file>"), 30 cl::init("-"), cl::value_desc("filename")); 31 32 static cl::opt<std::string> 33 OutputFilename("o", cl::desc("Specify output filename"), 34 cl::value_desc("filename"), cl::init("-")); 35 36 static cl::opt<bool> 37 Force("f", cl::desc("Overwrite output files")); 38 39 static cl::opt<bool> 40 DeleteFn("delete", cl::desc("Delete specified function from Module")); 41 42 // ExtractFunc - The function to extract from the module... defaults to main. 43 static cl::opt<std::string> 44 ExtractFunc("func", cl::desc("Specify function to extract"), cl::init("main"), 45 cl::value_desc("function")); 46 47 int main(int argc, char **argv) { 48 try { 49 cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n"); 50 sys::PrintStackTraceOnErrorSignal(); 51 52 std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); 53 if (M.get() == 0) { 54 std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; 55 return 1; 56 } 57 58 // Figure out which function we should extract 59 Function *F = M.get()->getNamedFunction(ExtractFunc); 60 if (F == 0) { 61 std::cerr << argv[0] << ": program doesn't contain function named '" 62 << ExtractFunc << "'!\n"; 63 return 1; 64 } 65 66 // In addition to deleting all other functions, we also want to spiff it 67 // up a little bit. Do this now. 68 PassManager Passes; 69 Passes.add(new TargetData("extract", M.get())); // Use correct TargetData 70 // Either isolate the function or delete it from the Module 71 Passes.add(createFunctionExtractionPass(F, DeleteFn)); 72 Passes.add(createGlobalDCEPass()); // Delete unreachable globals 73 Passes.add(createFunctionResolvingPass()); // Delete prototypes 74 Passes.add(createDeadTypeEliminationPass()); // Remove dead types... 75 76 std::ostream *Out = 0; 77 78 if (OutputFilename != "-") { // Not stdout? 79 if (!Force && std::ifstream(OutputFilename.c_str())) { 80 // If force is not specified, make sure not to overwrite a file! 81 std::cerr << argv[0] << ": error opening '" << OutputFilename 82 << "': file exists!\n" 83 << "Use -f command line argument to force output\n"; 84 return 1; 85 } 86 std::ios::openmode io_mode = std::ios::out | std::ios::trunc | 87 std::ios::binary; 88 Out = new std::ofstream(OutputFilename.c_str(), io_mode); 89 } else { // Specified stdout 90 // FIXME: cout is not binary! 91 Out = &std::cout; 92 } 93 94 Passes.add(new WriteBytecodePass(Out)); // Write bytecode to file... 95 Passes.run(*M.get()); 96 97 if (Out != &std::cout) 98 delete Out; 99 return 0; 100 } catch (const std::string& msg) { 101 std::cerr << argv[0] << ": " << msg << "\n"; 102 } catch (...) { 103 std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; 104 } 105 return 1; 106 } 107