X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=tools%2Fgold%2Fgold-plugin.cpp;h=a917ecfa502e4355d05b0f120766ccdb6e4d69a7;hb=0a1d37b2e85cc428a49e120ea5ac67003d0ab620;hp=e3a57b55f3342aa39bfbe0ec5c9873ae77f40bce;hpb=8d4343eb9b943727450b4ead2325d8e46e3f045e;p=oota-llvm.git diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index e3a57b55f33..a917ecfa502 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -20,6 +20,7 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/CommandFlags.h" +#include "llvm/CodeGen/ParallelCG.h" #include "llvm/IR/AutoUpgrade.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DiagnosticInfo.h" @@ -31,7 +32,7 @@ #include "llvm/Linker/Linker.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/Object/IRObjectFile.h" -#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Host.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -91,6 +92,8 @@ namespace options { }; static bool generate_api_file = false; static OutputType TheOutputType = OT_NORMAL; + static unsigned OptLevel = 2; + static unsigned Parallelism = 1; static std::string obj_path; static std::string extra_library_path; static std::string triple; @@ -102,7 +105,7 @@ namespace options { // use only and will not be passed. static std::vector extra; - static void process_plugin_option(const char* opt_) + static void process_plugin_option(const char *opt_) { if (opt_ == nullptr) return; @@ -124,6 +127,13 @@ namespace options { TheOutputType = OT_SAVE_TEMPS; } else if (opt == "disable-output") { TheOutputType = OT_DISABLE; + } else if (opt.size() == 2 && opt[0] == 'O') { + if (opt[1] < '0' || opt[1] > '3') + message(LDPL_FATAL, "Optimization level must be between 0 and 3"); + OptLevel = opt[1] - '0'; + } else if (opt.startswith("jobs=")) { + if (StringRef(opt_ + 5).getAsInteger(10, Parallelism)) + message(LDPL_FATAL, "Invalid parallelism level: %s", opt_ + 5); } else { // Save this option to pass to the code generator. // ParseCommandLineOptions() expects argv[0] to be program name. Lazily @@ -295,8 +305,8 @@ static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { case DS_Warning: Level = LDPL_WARNING; break; - case DS_Remark: case DS_Note: + case DS_Remark: Level = LDPL_INFO; break; } @@ -317,7 +327,8 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, message(LDPL_ERROR, "Failed to get a view of %s", file->name); return LDPS_ERR; } - BufferRef = MemoryBufferRef(StringRef((const char *)view, file->filesize), ""); + BufferRef = + MemoryBufferRef(StringRef((const char *)view, file->filesize), ""); } else { int64_t offset = 0; // Gold has found what might be IR part-way inside of a file, such as @@ -424,7 +435,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, } if (!cf.syms.empty()) { - if (add_symbols(cf.handle, cf.syms.size(), &cf.syms[0]) != LDPS_OK) { + if (add_symbols(cf.handle, cf.syms.size(), cf.syms.data()) != LDPS_OK) { message(LDPL_ERROR, "Unable to add symbols!"); return LDPS_ERR; } @@ -578,7 +589,7 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, ld_plugin_input_file &Info, raw_fd_ostream *ApiFile, StringSet<> &Internalize, StringSet<> &Maybe) { - if (get_symbols(F.handle, F.syms.size(), &F.syms[0]) != LDPS_OK) + if (get_symbols(F.handle, F.syms.size(), F.syms.data()) != LDPS_OK) message(LDPL_FATAL, "Failed to get symbol information"); const void *View; @@ -598,6 +609,7 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, Module &M = Obj.getModule(); + M.materializeMetadata(); UpgradeDebugInfo(M); SmallPtrSet Used; @@ -710,11 +722,9 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, } static void runLTOPasses(Module &M, TargetMachine &TM) { - if (const DataLayout *DL = TM.getDataLayout()) - M.setDataLayout(DL); + M.setDataLayout(TM.createDataLayout()); legacy::PassManager passes; - passes.add(new DataLayoutPass()); passes.add(createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis())); PassManagerBuilder PMB; @@ -724,6 +734,7 @@ static void runLTOPasses(Module &M, TargetMachine &TM) { PMB.VerifyOutput = true; PMB.LoopVectorize = true; PMB.SLPVectorize = true; + PMB.OptLevel = options::OptLevel; PMB.populateLTOPassManager(passes); passes.run(M); } @@ -733,11 +744,11 @@ static void saveBCFile(StringRef Path, Module &M) { raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None); if (EC) message(LDPL_FATAL, "Failed to write the output file."); - WriteBitcodeToFile(&M, OS); + WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true); } -static void codegen(Module &M) { - const std::string &TripleStr = M.getTargetTriple(); +static void codegen(std::unique_ptr M) { + const std::string &TripleStr = M->getTargetTriple(); Triple TheTriple(TripleStr); std::string ErrMsg; @@ -754,51 +765,77 @@ static void codegen(Module &M) { Features.AddFeature(A); TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); + CodeGenOpt::Level CGOptLevel; + switch (options::OptLevel) { + case 0: + CGOptLevel = CodeGenOpt::None; + break; + case 1: + CGOptLevel = CodeGenOpt::Less; + break; + case 2: + CGOptLevel = CodeGenOpt::Default; + break; + case 3: + CGOptLevel = CodeGenOpt::Aggressive; + break; + } std::unique_ptr TM(TheTarget->createTargetMachine( TripleStr, options::mcpu, Features.getString(), Options, RelocationModel, - CodeModel::Default, CodeGenOpt::Aggressive)); + CodeModel::Default, CGOptLevel)); - runLTOPasses(M, *TM); + runLTOPasses(*M, *TM); if (options::TheOutputType == options::OT_SAVE_TEMPS) - saveBCFile(output_name + ".opt.bc", M); - - legacy::PassManager CodeGenPasses; - CodeGenPasses.add(new DataLayoutPass()); + saveBCFile(output_name + ".opt.bc", *M); SmallString<128> Filename; - int FD; - if (options::obj_path.empty()) { - std::error_code EC = - sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); - if (EC) - message(LDPL_FATAL, "Could not create temporary file: %s", - EC.message().c_str()); - } else { + if (!options::obj_path.empty()) Filename = options::obj_path; - std::error_code EC = - sys::fs::openFileForWrite(Filename.c_str(), FD, sys::fs::F_None); - if (EC) - message(LDPL_FATAL, "Could not open file: %s", EC.message().c_str()); - } + else if (options::TheOutputType == options::OT_SAVE_TEMPS) + Filename = output_name + ".o"; + std::vector> Filenames(options::Parallelism); + bool TempOutFile = Filename.empty(); { - raw_fd_ostream OS(FD, true); - formatted_raw_ostream FOS(OS); + // Open a file descriptor for each backend thread. This is done in a block + // so that the output file descriptors are closed before gold opens them. + std::list OSs; + std::vector OSPtrs(options::Parallelism); + for (unsigned I = 0; I != options::Parallelism; ++I) { + int FD; + if (TempOutFile) { + std::error_code EC = + sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filenames[I]); + if (EC) + message(LDPL_FATAL, "Could not create temporary file: %s", + EC.message().c_str()); + } else { + Filenames[I] = Filename; + if (options::Parallelism != 1) + Filenames[I] += utostr(I); + std::error_code EC = + sys::fs::openFileForWrite(Filenames[I], FD, sys::fs::F_None); + if (EC) + message(LDPL_FATAL, "Could not open file: %s", EC.message().c_str()); + } + OSs.emplace_back(FD, true); + OSPtrs[I] = &OSs.back(); + } - if (TM->addPassesToEmitFile(CodeGenPasses, FOS, - TargetMachine::CGFT_ObjectFile)) - message(LDPL_FATAL, "Failed to setup codegen"); - CodeGenPasses.run(M); + // Run backend threads. + splitCodeGen(std::move(M), OSPtrs, options::mcpu, Features.getString(), + Options, RelocationModel, CodeModel::Default, CGOptLevel); } - if (add_input_file(Filename.c_str()) != LDPS_OK) - message(LDPL_FATAL, - "Unable to add .o file to the link. File left behind in: %s", - Filename.c_str()); - - if (options::obj_path.empty()) - Cleanup.push_back(Filename.c_str()); + for (auto &Filename : Filenames) { + if (add_input_file(Filename.c_str()) != LDPS_OK) + message(LDPL_FATAL, + "Unable to add .o file to the link. File left behind in: %s", + Filename.c_str()); + if (TempOutFile) + Cleanup.push_back(Filename.c_str()); + } } /// gold informs us that all symbols have been read. At this point, we use @@ -809,7 +846,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { return LDPS_OK; LLVMContext Context; - Context.setDiagnosticHandler(diagnosticHandler); + Context.setDiagnosticHandler(diagnosticHandler, nullptr, true); std::unique_ptr Combined(new Module("ld-temp.o", Context)); Linker L(Combined.get()); @@ -865,7 +902,7 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { return LDPS_OK; } - codegen(*L.getModule()); + codegen(std::move(Combined)); if (!options::extra_library_path.empty() && set_extra_library_path(options::extra_library_path.c_str()) != LDPS_OK)