summaryrefslogtreecommitdiff
path: root/lld/COFF/LTO.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/COFF/LTO.cpp')
-rw-r--r--lld/COFF/LTO.cpp61
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