Home | History | Annotate | Download | only in llvm-ndk-cc
      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