llvm-extract.cpp revision 065344dfd5a7b3502098810b981eb0077e5d81f3
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/Bitcode/ReaderWriter.h" 18#include "llvm/Transforms/IPO.h" 19#include "llvm/Target/TargetData.h" 20#include "llvm/Support/CommandLine.h" 21#include "llvm/Support/ManagedStatic.h" 22#include "llvm/Support/MemoryBuffer.h" 23#include "llvm/System/Signals.h" 24#include <iostream> 25#include <memory> 26#include <fstream> 27using namespace llvm; 28 29// InputFilename - The filename to read from. 30static cl::opt<std::string> 31InputFilename(cl::Positional, cl::desc("<input bytecode file>"), 32 cl::init("-"), cl::value_desc("filename")); 33 34static cl::opt<std::string> 35OutputFilename("o", cl::desc("Specify output filename"), 36 cl::value_desc("filename"), cl::init("-")); 37 38static cl::opt<bool> 39Force("f", cl::desc("Overwrite output files")); 40 41static cl::opt<bool> 42DeleteFn("delete", cl::desc("Delete specified function from Module")); 43 44static cl::opt<bool> 45Relink("relink", 46 cl::desc("Turn external linkage for callees of function to delete")); 47 48// ExtractFunc - The function to extract from the module... defaults to main. 49static cl::opt<std::string> 50ExtractFunc("func", cl::desc("Specify function to extract"), cl::init("main"), 51 cl::value_desc("function")); 52 53int main(int argc, char **argv) { 54 llvm_shutdown_obj X; // Call llvm_shutdown() on exit. 55 cl::ParseCommandLineOptions(argc, argv, " llvm extractor\n"); 56 sys::PrintStackTraceOnErrorSignal(); 57 58 std::auto_ptr<Module> M; 59 60 MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename); 61 if (Buffer == 0) { 62 cerr << "Error reading file '" + InputFilename + "'"; 63 return 1; 64 } else { 65 M.reset(ParseBitcodeFile(Buffer)); 66 } 67 delete Buffer; 68 69 if (M.get() == 0) { 70 cerr << argv[0] << ": bytecode didn't read correctly.\n"; 71 return 1; 72 } 73 74 // Figure out which function we should extract 75 Function *F = M.get()->getFunction(ExtractFunc); 76 if (F == 0) { 77 cerr << argv[0] << ": program doesn't contain function named '" 78 << ExtractFunc << "'!\n"; 79 return 1; 80 } 81 82 // In addition to deleting all other functions, we also want to spiff it 83 // up a little bit. Do this now. 84 PassManager Passes; 85 Passes.add(new TargetData(M.get())); // Use correct TargetData 86 // Either isolate the function or delete it from the Module 87 Passes.add(createFunctionExtractionPass(F, DeleteFn, Relink)); 88 if (!DeleteFn) 89 Passes.add(createGlobalDCEPass()); // Delete unreachable globals 90 Passes.add(createDeadTypeEliminationPass()); // Remove dead types... 91 Passes.add(createStripDeadPrototypesPass()); // Remove dead func decls 92 93 std::ostream *Out = 0; 94 95 if (OutputFilename != "-") { // Not stdout? 96 if (!Force && std::ifstream(OutputFilename.c_str())) { 97 // If force is not specified, make sure not to overwrite a file! 98 cerr << argv[0] << ": error opening '" << OutputFilename 99 << "': file exists!\n" 100 << "Use -f command line argument to force output\n"; 101 return 1; 102 } 103 std::ios::openmode io_mode = std::ios::out | std::ios::trunc | 104 std::ios::binary; 105 Out = new std::ofstream(OutputFilename.c_str(), io_mode); 106 } else { // Specified stdout 107 // FIXME: cout is not binary! 108 Out = &std::cout; 109 } 110 111 Passes.add(CreateBitcodeWriterPass(*Out)); 112 Passes.run(*M.get()); 113 114 if (Out != &std::cout) 115 delete Out; 116 return 0; 117} 118