1#include <cassert> 2#include <list> 3#include <string> 4 5#include "llvm/Linker.h" 6#include "llvm/LLVMContext.h" 7#include "llvm/Module.h" 8#include "llvm/PassManager.h" 9 10#include "llvm/ADT/OwningPtr.h" 11 12#include "llvm/Bitcode/ReaderWriter.h" 13 14#include "llvm/Support/CommandLine.h" 15#include "llvm/Support/ManagedStatic.h" 16#include "llvm/Support/MemoryBuffer.h" 17#include "llvm/Support/raw_ostream.h" 18#include "llvm/Transforms/IPO.h" 19#include "llvm/Transforms/IPO/PassManagerBuilder.h" 20#include "llvm/Support/system_error.h" 21 22#include "llvm/Target/TargetData.h" 23 24static llvm::cl::list<std::string> 25InputFilenames(llvm::cl::Positional, llvm::cl::OneOrMore, 26 llvm::cl::desc("<input bitcode files>")); 27 28static llvm::cl::list<std::string> 29OutputFilenames("o", llvm::cl::desc("Override output filename"), 30 llvm::cl::value_desc("output bitcode file")); 31 32 33static llvm::Module* getModuleFromFilename(std::string& Filename, 34 llvm::LLVMContext& Ctx, 35 std::string& ErrMsg) { 36 llvm::OwningPtr<llvm::MemoryBuffer> MB; 37 llvm::MemoryBuffer::getFile(Filename, MB); 38 llvm::Module* M = llvm::ParseBitcodeFile(MB.get(), Ctx, &ErrMsg); 39 assert(M && ErrMsg); 40 return M; 41} 42 43static void optimizeModule(llvm::Module* M) { 44 llvm::PassManager Passes; 45 46 const std::string &ModuleDataLayout = M->getDataLayout(); 47 if (!ModuleDataLayout.empty()) 48 if (llvm::TargetData *TD = new llvm::TargetData(ModuleDataLayout)) 49 Passes.add(TD); 50 51 Passes.add(llvm::createInternalizePass(true/* AllButMain*/)); 52#if 0 53 FIXME REMOVE 54 createStandardLTOPasses(&Passes, 55 /* Internalize = */false, 56 /* RunInliner = */true, 57 /* VerifyEach = */false); 58#endif 59 llvm::PassManagerBuilder PMBuilder; 60 PMBuilder.populateLTOPassManager(Passes, false, true); 61 Passes.run(*M); 62} 63 64static llvm::Module* linkFilesToModule(llvm::cl::list<std::string>& Inputs, 65 llvm::LLVMContext& Ctx) { 66 std::string ErrMsg; 67 llvm::Module* M = getModuleFromFilename(Inputs[0], Ctx, ErrMsg); 68 llvm::Linker Linker("llvm-ndk-link", M); 69 70 for (unsigned i=1; i<Inputs.size(); ++i) { 71 llvm::Module* M = getModuleFromFilename(Inputs[i], Ctx, ErrMsg); 72 if (!Linker.LinkInModule(M, &ErrMsg)) { 73 assert(false && ErrMsg); 74 } 75 optimizeModule(M); 76 } 77 M = Linker.releaseModule(); 78 79 llvm::PassManager PM; 80 const std::string &ModuleDataLayout = M->getDataLayout(); 81 if (!ModuleDataLayout.empty()) 82 if (llvm::TargetData *TD = new llvm::TargetData(ModuleDataLayout)) 83 PM.add(TD); 84 85#if 0 86 FIXME REMOVE 87 llvm::createStandardFunctionPasses(&PM, 3 /* OptLevel*/); 88 llvm::createStandardModulePasses(&PM, 89 3, /* OptimizationLevel */ 90 true, /* OptimizeSize */ 91 true, /* UnitAtATime */ 92 true, /* UnrollLoops */ 93 true, /* SimplifyLibCalls */ 94 false, /* HaveExceptions */ 95 NULL /* InliningPass */); 96#endif 97 98 llvm::PassManagerBuilder PMBuilder; 99 //PMBuilder.OptLevel = 3; 100 //PMBuilder.populateFunctionPassManager(PM); 101 102 PMBuilder.OptLevel = 3; 103 PMBuilder.SizeLevel = true; 104 PMBuilder.DisableUnitAtATime = false; 105 PMBuilder.DisableUnrollLoops = false; 106 PMBuilder.DisableSimplifyLibCalls = false; 107 PMBuilder.populateModulePassManager(PM); 108 109 PM.run(*M); 110 return M; 111} 112 113int main(int argc, char** argv) { 114 llvm::llvm_shutdown_obj _ShutdownObj; 115 llvm::cl::ParseCommandLineOptions(argc, argv, "P-NDK Link Tool"); 116 117 llvm::LLVMContext& Ctx = llvm::getGlobalContext(); 118 std::string ErrMsg; 119 llvm::raw_fd_ostream FOS(OutputFilenames[0].c_str(), ErrMsg); 120 assert(!FOS.has_error()); 121 122 // No need to link (just one file). 123 // Output Directly. 124 if (InputFilenames.size() == 1) { 125 llvm::OwningPtr<llvm::Module> M(getModuleFromFilename(InputFilenames[0], 126 Ctx, 127 ErrMsg)); 128 llvm::WriteBitcodeToFile(M.get(), FOS); 129 return 0; 130 } 131 132 llvm::OwningPtr<llvm::Module> M(linkFilesToModule(InputFilenames, Ctx)); 133 llvm::WriteBitcodeToFile(M.get(), FOS); 134 assert(!FOS.has_error()); 135 return 0; 136} 137