Reland "[LTO][COFF] Use bitcode file names in lto native object file names."
This reverts commit eef5405f74
.
This commit is contained in:
parent
48bb147112
commit
387620aa8c
|
@ -1110,7 +1110,7 @@ static void runThinLTOBackend(
|
|||
if (!lto::initImportList(*M, *CombinedIndex, ImportList))
|
||||
return;
|
||||
|
||||
auto AddStream = [&](size_t Task) {
|
||||
auto AddStream = [&](size_t Task, const Twine &ModuleName) {
|
||||
return std::make_unique<CachedFileStream>(std::move(OS),
|
||||
CGOpts.ObjectFilenameForDebug);
|
||||
};
|
||||
|
|
|
@ -843,7 +843,9 @@ Error linkBitcodeFiles(SmallVectorImpl<OffloadFile> &InputFiles,
|
|||
// Run the LTO job to compile the bitcode.
|
||||
size_t MaxTasks = LTOBackend->getMaxTasks();
|
||||
SmallVector<StringRef> Files(MaxTasks);
|
||||
auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
|
||||
auto AddStream =
|
||||
[&](size_t Task,
|
||||
const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
|
||||
int FD = -1;
|
||||
auto &TempFile = Files[Task];
|
||||
StringRef Extension = (Triple.isNVPTX()) ? "s" : "o";
|
||||
|
|
|
@ -165,22 +165,25 @@ std::vector<InputFile *> BitcodeCompiler::compile(COFFLinkerContext &ctx) {
|
|||
unsigned maxTasks = ltoObj->getMaxTasks();
|
||||
buf.resize(maxTasks);
|
||||
files.resize(maxTasks);
|
||||
file_names.resize(maxTasks);
|
||||
|
||||
// The /lldltocache option specifies the path to a directory in which to cache
|
||||
// native object files for ThinLTO incremental builds. If a path was
|
||||
// specified, configure LTO to use it as the cache directory.
|
||||
FileCache cache;
|
||||
if (!config->ltoCache.empty())
|
||||
cache =
|
||||
check(localCache("ThinLTO", "Thin", config->ltoCache,
|
||||
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
|
||||
files[task] = std::move(mb);
|
||||
}));
|
||||
cache = check(localCache("ThinLTO", "Thin", config->ltoCache,
|
||||
[&](size_t task, const Twine &moduleName,
|
||||
std::unique_ptr<MemoryBuffer> mb) {
|
||||
files[task] = std::move(mb);
|
||||
file_names[task] = moduleName.str();
|
||||
}));
|
||||
|
||||
checkError(ltoObj->run(
|
||||
[&](size_t task) {
|
||||
[&](size_t task, const Twine &moduleName) {
|
||||
buf[task].first = moduleName.str();
|
||||
return std::make_unique<CachedFileStream>(
|
||||
std::make_unique<raw_svector_ostream>(buf[task]));
|
||||
std::make_unique<raw_svector_ostream>(buf[task].second));
|
||||
},
|
||||
cache));
|
||||
|
||||
|
@ -197,7 +200,7 @@ std::vector<InputFile *> BitcodeCompiler::compile(COFFLinkerContext &ctx) {
|
|||
// distributed environment.
|
||||
if (config->thinLTOIndexOnly) {
|
||||
if (!config->ltoObjPath.empty())
|
||||
saveBuffer(buf[0], config->ltoObjPath);
|
||||
saveBuffer(buf[0].second, config->ltoObjPath);
|
||||
if (indexFile)
|
||||
indexFile->close();
|
||||
return {};
|
||||
|
@ -208,28 +211,40 @@ std::vector<InputFile *> BitcodeCompiler::compile(COFFLinkerContext &ctx) {
|
|||
|
||||
std::vector<InputFile *> ret;
|
||||
for (unsigned i = 0; i != maxTasks; ++i) {
|
||||
// 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");
|
||||
|
||||
StringRef bitcodeFilePath;
|
||||
// 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])
|
||||
if (files[i]) {
|
||||
objBuf = files[i]->getBuffer();
|
||||
else
|
||||
objBuf = buf[i];
|
||||
bitcodeFilePath = file_names[i];
|
||||
} else {
|
||||
objBuf = buf[i].second;
|
||||
bitcodeFilePath = buf[i].first;
|
||||
}
|
||||
if (objBuf.empty())
|
||||
continue;
|
||||
|
||||
// If the input bitcode file is path/to/a.obj, then the corresponding lto
|
||||
// object file name will soemthing like: path/to/main.exe.lto.a.obj.
|
||||
StringRef ltoObjName;
|
||||
if (bitcodeFilePath == "ld-temp.o") {
|
||||
ltoObjName =
|
||||
saver().save(Twine(config->outputFile) + ".lto" +
|
||||
(i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".obj");
|
||||
} else {
|
||||
StringRef directory = sys::path::parent_path(bitcodeFilePath);
|
||||
StringRef baseName = sys::path::filename(bitcodeFilePath);
|
||||
StringRef outputFileBaseName = sys::path::filename(config->outputFile);
|
||||
SmallString<64> path;
|
||||
sys::path::append(path, directory,
|
||||
outputFileBaseName + ".lto." + baseName);
|
||||
sys::path::remove_dots(path, true);
|
||||
ltoObjName = saver().save(path.str());
|
||||
}
|
||||
if (config->saveTemps)
|
||||
saveBuffer(buf[i], ltoObjName);
|
||||
saveBuffer(buf[i].second, ltoObjName);
|
||||
ret.push_back(make<ObjFile>(ctx, MemoryBufferRef(objBuf, ltoObjName)));
|
||||
}
|
||||
|
||||
|
|
|
@ -47,8 +47,9 @@ public:
|
|||
|
||||
private:
|
||||
std::unique_ptr<llvm::lto::LTO> ltoObj;
|
||||
std::vector<SmallString<0>> buf;
|
||||
std::vector<std::pair<std::string, SmallString<0>>> buf;
|
||||
std::vector<std::unique_ptr<MemoryBuffer>> files;
|
||||
std::vector<std::string> file_names;
|
||||
std::unique_ptr<llvm::raw_fd_ostream> indexFile;
|
||||
llvm::DenseSet<StringRef> thinIndices;
|
||||
};
|
||||
|
|
|
@ -327,15 +327,15 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
|
|||
// specified, configure LTO to use it as the cache directory.
|
||||
FileCache cache;
|
||||
if (!config->thinLTOCacheDir.empty())
|
||||
cache =
|
||||
check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
|
||||
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
|
||||
files[task] = std::move(mb);
|
||||
}));
|
||||
cache = check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
|
||||
[&](size_t task, const Twine &moduleName,
|
||||
std::unique_ptr<MemoryBuffer> mb) {
|
||||
files[task] = std::move(mb);
|
||||
}));
|
||||
|
||||
if (!ctx.bitcodeFiles.empty())
|
||||
checkError(ltoObj->run(
|
||||
[&](size_t task) {
|
||||
[&](size_t task, const Twine &moduleName) {
|
||||
return std::make_unique<CachedFileStream>(
|
||||
std::make_unique<raw_svector_ostream>(buf[task]));
|
||||
},
|
||||
|
|
|
@ -129,14 +129,14 @@ std::vector<ObjFile *> BitcodeCompiler::compile() {
|
|||
// specified, configure LTO to use it as the cache directory.
|
||||
FileCache cache;
|
||||
if (!config->thinLTOCacheDir.empty())
|
||||
cache =
|
||||
check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
|
||||
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
|
||||
files[task] = std::move(mb);
|
||||
}));
|
||||
cache = check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
|
||||
[&](size_t task, const Twine &moduleName,
|
||||
std::unique_ptr<MemoryBuffer> mb) {
|
||||
files[task] = std::move(mb);
|
||||
}));
|
||||
|
||||
checkError(ltoObj->run(
|
||||
[&](size_t task) {
|
||||
[&](size_t task, const Twine &moduleName) {
|
||||
return std::make_unique<CachedFileStream>(
|
||||
std::make_unique<raw_svector_ostream>(buf[task]));
|
||||
},
|
||||
|
|
|
@ -2,26 +2,31 @@
|
|||
|
||||
; Test to ensure that thinlto-index-only with lto-obj-path creates
|
||||
; the native object file.
|
||||
; RUN: opt -module-summary %s -o %t1.obj
|
||||
; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t2.obj
|
||||
; RUN: rm -f %t4.obj
|
||||
; RUN: lld-link -thinlto-index-only -lto-obj-path:%t4.obj -out:t3.exe \
|
||||
; RUN: -entry:main %t1.obj %t2.obj
|
||||
; RUN: llvm-readobj -h %t4.obj | FileCheck %s
|
||||
; RUN: llvm-nm %t4.obj 2>&1 | FileCheck %s -check-prefix=SYMBOLS
|
||||
; RUN: llvm-nm %t4.obj 2>&1 | count 1
|
||||
; RUN: rm -rf %t.dir/objpath && mkdir -p %t.dir/objpath
|
||||
; RUN: opt -module-summary %s -o %t.dir/objpath/t1.obj
|
||||
; RUN: opt -module-summary %p/Inputs/thinlto.ll -o %t.dir/objpath/t2.obj
|
||||
; RUN: rm -f %t.dir/objpath/t4.obj
|
||||
; RUN: lld-link -thinlto-index-only -lto-obj-path:%t.dir/objpath/t4.obj \
|
||||
; RUN: -out:%t.dir/objpath/t3.exe -entry:main %t.dir/objpath/t1.obj \
|
||||
; RUN: %t.dir/objpath/t2.obj
|
||||
; RUN: llvm-readobj -h %t.dir/objpath/t4.obj | FileCheck %s
|
||||
; RUN: llvm-nm %t.dir/objpath/t4.obj 2>&1 | FileCheck %s -check-prefix=SYMBOLS
|
||||
; RUN: llvm-nm %t.dir/objpath/t4.obj 2>&1 | count 1
|
||||
|
||||
;; Ensure lld emits empty combined module if specific obj-path.
|
||||
; RUN: rm -fr %t.dir/objpath && mkdir -p %t.dir/objpath
|
||||
; RUN: lld-link /out:%t.dir/objpath/a.exe -lto-obj-path:%t4.obj \
|
||||
; RUN: -entry:main %t1.obj %t2.obj -lldsavetemps
|
||||
; RUN: ls %t.dir/objpath/a.exe.lto.* | count 3
|
||||
; RUN: lld-link /out:%t.dir/objpath/a.exe -lto-obj-path:%t.dir/objpath/t4.obj \
|
||||
; RUN: -entry:main %t.dir/objpath/t1.obj %t.dir/objpath/t2.obj -lldsavetemps
|
||||
; RUN: ls %t.dir/objpath/a.exe.lto.obj
|
||||
; RUN: ls %t.dir/objpath/a.exe.lto.t1.obj
|
||||
; RUN: ls %t.dir/objpath/a.exe.lto.t2.obj
|
||||
|
||||
;; Ensure lld does not emit empty combined module in default.
|
||||
; RUN: rm -fr %t.dir/objpath && mkdir -p %t.dir/objpath
|
||||
; RUN: rm %t.dir/objpath/a.exe.lto.*
|
||||
; RUN: lld-link /out:%t.dir/objpath/a.exe \
|
||||
; RUN: -entry:main %t1.obj %t2.obj -lldsavetemps
|
||||
; RUN: ls %t.dir/objpath/a.exe.lto.* | count 2
|
||||
; RUN: -entry:main %t.dir/objpath/t1.obj %t.dir/objpath/t2.obj -lldsavetemps
|
||||
; RUN: ls %t.dir/objpath/a.exe.lto.t1.obj
|
||||
; RUN: ls %t.dir/objpath/a.exe.lto.t2.obj
|
||||
; RUN: not ls %t.dir/objpath/a.exe.lto.obj
|
||||
|
||||
; CHECK: Format: COFF-x86-64
|
||||
; SYMBOLS: @feat.00
|
||||
|
|
|
@ -29,8 +29,8 @@ declare void @foo()
|
|||
|
||||
; CHECK: Modules
|
||||
; CHECK: ============================================================
|
||||
; CHECK: Mod 0000 | `{{.*}}main.exe.lto.1.obj`:
|
||||
; CHECK: Obj: `{{.*}}main.exe.lto.1.obj`:
|
||||
; CHECK: Mod 0001 | `{{.*}}main.exe.lto.2.obj`:
|
||||
; CHECK: Obj: `{{.*}}main.exe.lto.2.obj`:
|
||||
; CHECK: Mod 0000 | `{{.*}}main.exe.lto.main.bc`:
|
||||
; CHECK: Obj: `{{.*}}main.exe.lto.main.bc`:
|
||||
; CHECK: Mod 0001 | `{{.*}}main.exe.lto.foo.bc`:
|
||||
; CHECK: Obj: `{{.*}}main.exe.lto.foo.bc`:
|
||||
; CHECK: Mod 0002 | `* Linker *`:
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
; RUN: opt -thinlto-bc -o %T/thinlto/main.obj %s
|
||||
; RUN: opt -thinlto-bc -o %T/thinlto/foo.obj %S/Inputs/lto-dep.ll
|
||||
; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj
|
||||
; RUN: llvm-nm %T/thinlto/main.exe.lto.1.obj | FileCheck %s
|
||||
; RUN: llvm-nm %T/thinlto/main.exe.lto.foo.obj | FileCheck %s
|
||||
|
||||
; Test various possible options for /opt:lldltojobs
|
||||
; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj /opt:lldltojobs=1
|
||||
; RUN: llvm-nm %T/thinlto/main.exe.lto.1.obj | FileCheck %s
|
||||
; RUN: llvm-nm %T/thinlto/main.exe.lto.foo.obj | FileCheck %s
|
||||
; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj /opt:lldltojobs=all
|
||||
; RUN: llvm-nm %T/thinlto/main.exe.lto.1.obj | FileCheck %s
|
||||
; RUN: llvm-nm %T/thinlto/main.exe.lto.foo.obj | FileCheck %s
|
||||
; RUN: lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj /opt:lldltojobs=100
|
||||
; RUN: llvm-nm %T/thinlto/main.exe.lto.1.obj | FileCheck %s
|
||||
; RUN: llvm-nm %T/thinlto/main.exe.lto.foo.obj | FileCheck %s
|
||||
; RUN: not lld-link /lldsavetemps /out:%T/thinlto/main.exe /entry:main /subsystem:console %T/thinlto/main.obj %T/thinlto/foo.obj /opt:lldltojobs=foo 2>&1 | FileCheck %s --check-prefix=BAD-JOBS
|
||||
; BAD-JOBS: error: /opt:lldltojobs: invalid job count: foo
|
||||
|
||||
|
|
|
@ -128,14 +128,14 @@ std::vector<StringRef> BitcodeCompiler::compile() {
|
|||
// specified, configure LTO to use it as the cache directory.
|
||||
FileCache cache;
|
||||
if (!config->thinLTOCacheDir.empty())
|
||||
cache =
|
||||
check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
|
||||
[&](size_t task, std::unique_ptr<MemoryBuffer> mb) {
|
||||
files[task] = std::move(mb);
|
||||
}));
|
||||
cache = check(localCache("ThinLTO", "Thin", config->thinLTOCacheDir,
|
||||
[&](size_t task, const Twine &moduleName,
|
||||
std::unique_ptr<MemoryBuffer> mb) {
|
||||
files[task] = std::move(mb);
|
||||
}));
|
||||
|
||||
checkError(ltoObj->run(
|
||||
[&](size_t task) {
|
||||
[&](size_t task, const Twine &moduleName) {
|
||||
return std::make_unique<CachedFileStream>(
|
||||
std::make_unique<raw_svector_ostream>(buf[task]));
|
||||
},
|
||||
|
|
|
@ -54,7 +54,8 @@ DataFileCache::DataFileCache(llvm::StringRef path, llvm::CachePruningPolicy poli
|
|||
// m_take_ownership member variable to indicate if we need to take
|
||||
// ownership.
|
||||
|
||||
auto add_buffer = [this](unsigned task, std::unique_ptr<llvm::MemoryBuffer> m) {
|
||||
auto add_buffer = [this](unsigned task, const llvm::Twine &moduleName,
|
||||
std::unique_ptr<llvm::MemoryBuffer> m) {
|
||||
if (m_take_ownership)
|
||||
m_mem_buff_up = std::move(m);
|
||||
};
|
||||
|
@ -80,7 +81,7 @@ DataFileCache::GetCachedData(llvm::StringRef key) {
|
|||
// turn take ownership of the member buffer that is passed to the callback and
|
||||
// put it into a member variable.
|
||||
llvm::Expected<llvm::AddStreamFn> add_stream_or_err =
|
||||
m_cache_callback(task, key);
|
||||
m_cache_callback(task, key, "");
|
||||
m_take_ownership = false;
|
||||
// At this point we either already called the "add_buffer" lambda with
|
||||
// the data or we haven't. We can tell if we got the cached data by checking
|
||||
|
@ -112,7 +113,7 @@ bool DataFileCache::SetCachedData(llvm::StringRef key,
|
|||
// add_buffer lambda function from the constructor which will ignore the
|
||||
// data.
|
||||
llvm::Expected<llvm::AddStreamFn> add_stream_or_err =
|
||||
m_cache_callback(task, key);
|
||||
m_cache_callback(task, key, "");
|
||||
// If we reach this code then we either already called the callback with
|
||||
// the data or we haven't. We can tell if we had the cached data by checking
|
||||
// the CacheAddStream function pointer value below.
|
||||
|
@ -127,7 +128,7 @@ bool DataFileCache::SetCachedData(llvm::StringRef key,
|
|||
// want to write the data.
|
||||
if (add_stream) {
|
||||
llvm::Expected<std::unique_ptr<llvm::CachedFileStream>> file_or_err =
|
||||
add_stream(task);
|
||||
add_stream(task, "");
|
||||
if (file_or_err) {
|
||||
llvm::CachedFileStream *cfs = file_or_err->get();
|
||||
cfs->OS->write((const char *)data.data(), data.size());
|
||||
|
|
|
@ -38,28 +38,30 @@ public:
|
|||
/// This type defines the callback to add a file that is generated on the fly.
|
||||
///
|
||||
/// Stream callbacks must be thread safe.
|
||||
using AddStreamFn =
|
||||
std::function<Expected<std::unique_ptr<CachedFileStream>>(unsigned Task)>;
|
||||
using AddStreamFn = std::function<Expected<std::unique_ptr<CachedFileStream>>(
|
||||
unsigned Task, const Twine &ModuleName)>;
|
||||
|
||||
/// This is the type of a file cache. To request an item from the cache, pass a
|
||||
/// unique string as the Key. For hits, the cached file will be added to the
|
||||
/// link and this function will return AddStreamFn(). For misses, the cache will
|
||||
/// return a stream callback which must be called at most once to produce
|
||||
/// content for the stream. The file stream produced by the stream callback will
|
||||
/// add the file to the link after the stream is written to.
|
||||
/// add the file to the link after the stream is written to. ModuleName is the
|
||||
/// unique module identifier for the bitcode module the cache is being checked
|
||||
/// for.
|
||||
///
|
||||
/// Clients generally look like this:
|
||||
///
|
||||
/// if (AddStreamFn AddStream = Cache(Task, Key))
|
||||
/// if (AddStreamFn AddStream = Cache(Task, Key, ModuleName))
|
||||
/// ProduceContent(AddStream);
|
||||
using FileCache =
|
||||
std::function<Expected<AddStreamFn>(unsigned Task, StringRef Key)>;
|
||||
using FileCache = std::function<Expected<AddStreamFn>(
|
||||
unsigned Task, StringRef Key, const Twine &ModuleName)>;
|
||||
|
||||
/// This type defines the callback to add a pre-existing file (e.g. in a cache).
|
||||
///
|
||||
/// Buffer callbacks must be thread safe.
|
||||
using AddBufferFn =
|
||||
std::function<void(unsigned Task, std::unique_ptr<MemoryBuffer> MB)>;
|
||||
using AddBufferFn = std::function<void(unsigned Task, const Twine &ModuleName,
|
||||
std::unique_ptr<MemoryBuffer> MB)>;
|
||||
|
||||
/// Create a local file system cache which uses the given cache name, temporary
|
||||
/// file prefix, cache directory and file callback. This function does not
|
||||
|
@ -68,9 +70,10 @@ using AddBufferFn =
|
|||
/// messages for errors during caching. The temporary file prefix is used in the
|
||||
/// temporary file naming scheme used when writing files atomically.
|
||||
Expected<FileCache> localCache(
|
||||
Twine CacheNameRef, Twine TempFilePrefixRef, Twine CacheDirectoryPathRef,
|
||||
AddBufferFn AddBuffer = [](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
|
||||
});
|
||||
const Twine &CacheNameRef, const Twine &TempFilePrefixRef,
|
||||
const Twine &CacheDirectoryPathRef,
|
||||
AddBufferFn AddBuffer = [](size_t Task, const Twine &ModuleName,
|
||||
std::unique_ptr<MemoryBuffer> MB) {});
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
|
|
|
@ -224,7 +224,7 @@ Expected<std::string> getCachedOrDownloadArtifact(
|
|||
FileCache Cache = *CacheOrErr;
|
||||
// We choose an arbitrary Task parameter as we do not make use of it.
|
||||
unsigned Task = 0;
|
||||
Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, UniqueKey);
|
||||
Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, UniqueKey, "");
|
||||
if (!CacheAddStreamOrErr)
|
||||
return CacheAddStreamOrErr.takeError();
|
||||
AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
|
||||
|
@ -251,8 +251,8 @@ Expected<std::string> getCachedOrDownloadArtifact(
|
|||
|
||||
// Perform the HTTP request and if successful, write the response body to
|
||||
// the cache.
|
||||
StreamedHTTPResponseHandler Handler([&]() { return CacheAddStream(Task); },
|
||||
Client);
|
||||
StreamedHTTPResponseHandler Handler(
|
||||
[&]() { return CacheAddStream(Task, ""); }, Client);
|
||||
HTTPRequest Request(ArtifactUrl);
|
||||
Request.Headers = getHeaders();
|
||||
Error Err = Client.perform(Request, Handler);
|
||||
|
|
|
@ -1313,7 +1313,7 @@ public:
|
|||
computeLTOCacheKey(Key, Conf, CombinedIndex, ModuleID, ImportList,
|
||||
ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs,
|
||||
CfiFunctionDecls);
|
||||
Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key);
|
||||
Expected<AddStreamFn> CacheAddStreamOrErr = Cache(Task, Key, ModuleID);
|
||||
if (Error Err = CacheAddStreamOrErr.takeError())
|
||||
return Err;
|
||||
AddStreamFn &CacheAddStream = *CacheAddStreamOrErr;
|
||||
|
|
|
@ -391,7 +391,8 @@ static void codegen(const Config &Conf, TargetMachine *TM,
|
|||
EC.message());
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<CachedFileStream>> StreamOrErr = AddStream(Task);
|
||||
Expected<std::unique_ptr<CachedFileStream>> StreamOrErr =
|
||||
AddStream(Task, Mod.getModuleIdentifier());
|
||||
if (Error Err = StreamOrErr.takeError())
|
||||
report_fatal_error(std::move(Err));
|
||||
std::unique_ptr<CachedFileStream> &Stream = *StreamOrErr;
|
||||
|
|
|
@ -301,7 +301,9 @@ bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
|
|||
// make unique temp output file to put generated code
|
||||
SmallString<128> Filename;
|
||||
|
||||
auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
|
||||
auto AddStream =
|
||||
[&](size_t Task,
|
||||
const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
|
||||
StringRef Extension(Config.CGFileType == CGFT_AssemblyFile ? "s" : "o");
|
||||
|
||||
int FD;
|
||||
|
|
|
@ -26,9 +26,9 @@
|
|||
|
||||
using namespace llvm;
|
||||
|
||||
Expected<FileCache> llvm::localCache(Twine CacheNameRef,
|
||||
Twine TempFilePrefixRef,
|
||||
Twine CacheDirectoryPathRef,
|
||||
Expected<FileCache> llvm::localCache(const Twine &CacheNameRef,
|
||||
const Twine &TempFilePrefixRef,
|
||||
const Twine &CacheDirectoryPathRef,
|
||||
AddBufferFn AddBuffer) {
|
||||
|
||||
// Create local copies which are safely captured-by-copy in lambdas
|
||||
|
@ -37,7 +37,8 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
|
|||
TempFilePrefixRef.toVector(TempFilePrefix);
|
||||
CacheDirectoryPathRef.toVector(CacheDirectoryPath);
|
||||
|
||||
return [=](unsigned Task, StringRef Key) -> Expected<AddStreamFn> {
|
||||
return [=](unsigned Task, StringRef Key,
|
||||
const Twine &ModuleName) -> Expected<AddStreamFn> {
|
||||
// This choice of file name allows the cache to be pruned (see pruneCache()
|
||||
// in include/llvm/Support/CachePruning.h).
|
||||
SmallString<64> EntryPath;
|
||||
|
@ -54,7 +55,7 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
|
|||
/*RequiresNullTerminator=*/false);
|
||||
sys::fs::closeFile(*FDOrErr);
|
||||
if (MBOrErr) {
|
||||
AddBuffer(Task, std::move(*MBOrErr));
|
||||
AddBuffer(Task, ModuleName, std::move(*MBOrErr));
|
||||
return AddStreamFn();
|
||||
}
|
||||
EC = MBOrErr.getError();
|
||||
|
@ -77,14 +78,15 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
|
|||
struct CacheStream : CachedFileStream {
|
||||
AddBufferFn AddBuffer;
|
||||
sys::fs::TempFile TempFile;
|
||||
std::string ModuleName;
|
||||
unsigned Task;
|
||||
|
||||
CacheStream(std::unique_ptr<raw_pwrite_stream> OS, AddBufferFn AddBuffer,
|
||||
sys::fs::TempFile TempFile, std::string EntryPath,
|
||||
unsigned Task)
|
||||
std::string ModuleName, unsigned Task)
|
||||
: CachedFileStream(std::move(OS), std::move(EntryPath)),
|
||||
AddBuffer(std::move(AddBuffer)), TempFile(std::move(TempFile)),
|
||||
Task(Task) {}
|
||||
ModuleName(ModuleName), Task(Task) {}
|
||||
|
||||
~CacheStream() {
|
||||
// TODO: Manually commit rather than using non-trivial destructor,
|
||||
|
@ -133,11 +135,12 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
|
|||
TempFile.TmpName + " to " + ObjectPathName + ": " +
|
||||
toString(std::move(E)) + "\n");
|
||||
|
||||
AddBuffer(Task, std::move(*MBOrErr));
|
||||
AddBuffer(Task, ModuleName, std::move(*MBOrErr));
|
||||
}
|
||||
};
|
||||
|
||||
return [=](size_t Task) -> Expected<std::unique_ptr<CachedFileStream>> {
|
||||
return [=](size_t Task, const Twine &ModuleName)
|
||||
-> Expected<std::unique_ptr<CachedFileStream>> {
|
||||
// Create the cache directory if not already done. Doing this lazily
|
||||
// ensures the filesystem isn't mutated until the cache is.
|
||||
if (std::error_code EC = sys::fs::create_directories(
|
||||
|
@ -158,7 +161,8 @@ Expected<FileCache> llvm::localCache(Twine CacheNameRef,
|
|||
// This CacheStream will move the temporary file into the cache when done.
|
||||
return std::make_unique<CacheStream>(
|
||||
std::make_unique<raw_fd_ostream>(Temp->FD, /* ShouldClose */ false),
|
||||
AddBuffer, std::move(*Temp), std::string(EntryPath.str()), Task);
|
||||
AddBuffer, std::move(*Temp), std::string(EntryPath.str()),
|
||||
ModuleName.str(), Task);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -317,11 +317,11 @@ namespace {
|
|||
if (!CurrentActivity.empty())
|
||||
OS << ' ' << CurrentActivity;
|
||||
OS << ": ";
|
||||
|
||||
|
||||
DiagnosticPrinterRawOStream DP(OS);
|
||||
DI.print(DP);
|
||||
OS << '\n';
|
||||
|
||||
|
||||
if (DI.getSeverity() == DS_Error)
|
||||
exit(1);
|
||||
return true;
|
||||
|
@ -1099,7 +1099,9 @@ int main(int argc, char **argv) {
|
|||
error("writing merged module failed.");
|
||||
}
|
||||
|
||||
auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
|
||||
auto AddStream =
|
||||
[&](size_t Task,
|
||||
const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
|
||||
std::string PartFilename = OutputFilename;
|
||||
if (Parallelism != 1)
|
||||
PartFilename += "." + utostr(Task);
|
||||
|
|
|
@ -411,7 +411,9 @@ static int run(int argc, char **argv) {
|
|||
if (HasErrors)
|
||||
return 1;
|
||||
|
||||
auto AddStream = [&](size_t Task) -> std::unique_ptr<CachedFileStream> {
|
||||
auto AddStream =
|
||||
[&](size_t Task,
|
||||
const Twine &ModuleName) -> std::unique_ptr<CachedFileStream> {
|
||||
std::string Path = OutputFilename + "." + utostr(Task);
|
||||
|
||||
std::error_code EC;
|
||||
|
@ -420,8 +422,9 @@ static int run(int argc, char **argv) {
|
|||
return std::make_unique<CachedFileStream>(std::move(S), Path);
|
||||
};
|
||||
|
||||
auto AddBuffer = [&](size_t Task, std::unique_ptr<MemoryBuffer> MB) {
|
||||
*AddStream(Task)->OS << MB->getBuffer();
|
||||
auto AddBuffer = [&](size_t Task, const Twine &ModuleName,
|
||||
std::unique_ptr<MemoryBuffer> MB) {
|
||||
*AddStream(Task, ModuleName)->OS << MB->getBuffer();
|
||||
};
|
||||
|
||||
FileCache Cache;
|
||||
|
|
Loading…
Reference in New Issue