mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[dsymutil] Apply recursion workaround for threading
The DwarfLinker can have some very deep recursion that can max out the (significantly smaller) stack when using threads. We don't want this limitation when we only have a single thread. We already have this workaround for the architecture-related threading. This patch applies the same workaround to the parallel analysis and cloning. Differential revision: https://reviews.llvm.org/D45172 llvm-svn: 329093
This commit is contained in:
parent
5ccce5550d
commit
3351ebfb30
@ -4301,8 +4301,6 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
if (MaxDwarfVersion == 0)
|
||||
MaxDwarfVersion = 3;
|
||||
|
||||
ThreadPool pool(2);
|
||||
|
||||
// These variables manage the list of processed object files.
|
||||
// The mutex and condition variable are to ensure that this is thread safe.
|
||||
std::mutex ProcessedFilesMutex;
|
||||
@ -4310,7 +4308,7 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
BitVector ProcessedFiles(NumObjects, false);
|
||||
|
||||
// Now do analyzeContextInfo in parallel as it is particularly expensive.
|
||||
pool.async([&]() {
|
||||
auto AnalyzeLambda = [&]() {
|
||||
for (unsigned i = 0, e = NumObjects; i != e; ++i) {
|
||||
auto &LinkContext = ObjectContexts[i];
|
||||
|
||||
@ -4331,13 +4329,13 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
ProcessedFiles.set(i);
|
||||
ProcessedFilesConditionVariable.notify_one();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// And then the remaining work in serial again.
|
||||
// Note, although this loop runs in serial, it can run in parallel with
|
||||
// the analyzeContextInfo loop so long as we process files with indices >=
|
||||
// than those processed by analyzeContextInfo.
|
||||
pool.async([&]() {
|
||||
auto CloneLambda = [&]() {
|
||||
for (unsigned i = 0, e = NumObjects; i != e; ++i) {
|
||||
{
|
||||
std::unique_lock<std::mutex> LockGuard(ProcessedFilesMutex);
|
||||
@ -4397,9 +4395,20 @@ bool DwarfLinker::link(const DebugMap &Map) {
|
||||
Streamer->emitAppleTypes(AppleTypes);
|
||||
Streamer->emitAppleObjc(AppleObjc);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
pool.wait();
|
||||
// FIXME: The DwarfLinker can have some very deep recursion that can max
|
||||
// out the (significantly smaller) stack when using threads. We don't
|
||||
// want this limitation when we only have a single thread.
|
||||
if (Options.Threads == 1) {
|
||||
AnalyzeLambda();
|
||||
CloneLambda();
|
||||
} else {
|
||||
ThreadPool pool(2);
|
||||
pool.async(AnalyzeLambda);
|
||||
pool.async(CloneLambda);
|
||||
pool.wait();
|
||||
}
|
||||
|
||||
return Options.NoOutput ? true : Streamer->finish(Map);
|
||||
}
|
||||
|
@ -324,6 +324,11 @@ static Expected<LinkOptions> getOptions() {
|
||||
inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
if (NumThreads == 0)
|
||||
Options.Threads = llvm::thread::hardware_concurrency();
|
||||
if (DumpDebugMap || Verbose)
|
||||
Options.Threads = 1;
|
||||
|
||||
return Options;
|
||||
}
|
||||
|
||||
@ -480,12 +485,8 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (NumThreads == 0)
|
||||
NumThreads = llvm::thread::hardware_concurrency();
|
||||
if (DumpDebugMap || Verbose)
|
||||
NumThreads = 1;
|
||||
NumThreads = std::min<unsigned>(NumThreads, DebugMapPtrsOrErr->size());
|
||||
|
||||
NumThreads =
|
||||
std::min<unsigned>(OptionsOrErr->Threads, DebugMapPtrsOrErr->size());
|
||||
llvm::ThreadPool Threads(NumThreads);
|
||||
|
||||
// If there is more than one link to execute, we need to generate
|
||||
|
@ -48,6 +48,9 @@ struct LinkOptions {
|
||||
/// Do not check swiftmodule timestamp
|
||||
bool NoTimestamp = false;
|
||||
|
||||
/// Number of threads.
|
||||
unsigned Threads = 1;
|
||||
|
||||
/// -oso-prepend-path
|
||||
std::string PrependPath;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user