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