diff options
Diffstat (limited to 'lld/COFF/LTO.cpp')
-rw-r--r-- | lld/COFF/LTO.cpp | 61 |
1 files changed, 35 insertions, 26 deletions
diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp index 1c21236dce2b..bb44819e60f8 100644 --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -38,9 +38,8 @@ using namespace llvm; using namespace llvm::object; - -namespace lld { -namespace coff { +using namespace lld; +using namespace lld::coff; // Creates an empty file to and returns a raw_fd_ostream to write to it. static std::unique_ptr<raw_fd_ostream> openFile(StringRef file) { @@ -55,9 +54,9 @@ static std::unique_ptr<raw_fd_ostream> openFile(StringRef file) { } static std::string getThinLTOOutputFile(StringRef path) { - return lto::getThinLTOOutputFile(path, - config->thinLTOPrefixReplace.first, - config->thinLTOPrefixReplace.second); + return lto::getThinLTOOutputFile( + std::string(path), std::string(config->thinLTOPrefixReplace.first), + std::string(config->thinLTOPrefixReplace.second)); } static lto::Config createConfig() { @@ -82,6 +81,7 @@ static lto::Config createConfig() { c.CPU = getCPUStr(); c.MAttrs = getMAttrs(); c.CGOptLevel = args::getCGOptLevel(config->ltoo); + c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty(); if (config->saveTemps) checkError(c.addSaveTemps(std::string(config->outputFile) + ".", @@ -99,10 +99,12 @@ BitcodeCompiler::BitcodeCompiler() { if (config->thinLTOIndexOnly) { auto OnIndexWrite = [&](StringRef S) { thinIndices.erase(S); }; backend = lto::createWriteIndexesThinBackend( - config->thinLTOPrefixReplace.first, config->thinLTOPrefixReplace.second, + std::string(config->thinLTOPrefixReplace.first), + std::string(config->thinLTOPrefixReplace.second), config->thinLTOEmitImportsFiles, indexFile.get(), OnIndexWrite); - } else if (config->thinLTOJobs != 0) { - backend = lto::createInProcessThinBackend(config->thinLTOJobs); + } else { + backend = lto::createInProcessThinBackend( + llvm::heavyweight_hardware_concurrency(config->thinLTOJobs)); } ltoObj = std::make_unique<lto::LTO>(createConfig(), backend, @@ -143,7 +145,7 @@ void BitcodeCompiler::add(BitcodeFile &f) { // Merge all the bitcode files we have seen, codegen the result // and return the resulting objects. -std::vector<StringRef> BitcodeCompiler::compile() { +std::vector<InputFile *> BitcodeCompiler::compile() { unsigned maxTasks = ltoObj->getMaxTasks(); buf.resize(maxTasks); files.resize(maxTasks); @@ -187,25 +189,32 @@ std::vector<StringRef> BitcodeCompiler::compile() { if (!config->ltoCache.empty()) pruneCache(config->ltoCache, config->ltoCachePolicy); - std::vector<StringRef> ret; + std::vector<InputFile *> ret; for (unsigned i = 0; i != maxTasks; ++i) { - if (buf[i].empty()) + // Assign unique names to LTO objects. This ensures they have unique names + // in the PDB if one is produced. The names should look like: + // - foo.exe.lto.obj + // - foo.exe.lto.1.obj + // - ... + StringRef ltoObjName = + saver.save(Twine(config->outputFile) + ".lto" + + (i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".obj"); + + // Get the native object contents either from the cache or from memory. Do + // not use the cached MemoryBuffer directly, or the PDB will not be + // deterministic. + StringRef objBuf; + if (files[i]) + objBuf = files[i]->getBuffer(); + else + objBuf = buf[i]; + if (objBuf.empty()) continue; - if (config->saveTemps) { - if (i == 0) - saveBuffer(buf[i], config->outputFile + ".lto.obj"); - else - saveBuffer(buf[i], config->outputFile + Twine(i) + ".lto.obj"); - } - ret.emplace_back(buf[i].data(), buf[i].size()); - } - for (std::unique_ptr<MemoryBuffer> &file : files) - if (file) - ret.push_back(file->getBuffer()); + if (config->saveTemps) + saveBuffer(buf[i], ltoObjName); + ret.push_back(make<ObjFile>(MemoryBufferRef(objBuf, ltoObjName))); + } return ret; } - -} // namespace coff -} // namespace lld |