Index: llvm/trunk/tools/dsymutil/DwarfLinker.cpp =================================================================== --- llvm/trunk/tools/dsymutil/DwarfLinker.cpp +++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp @@ -4301,8 +4301,6 @@ 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 @@ 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 @@ 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 LockGuard(ProcessedFilesMutex); @@ -4397,9 +4395,20 @@ 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); } Index: llvm/trunk/tools/dsymutil/dsymutil.h =================================================================== --- llvm/trunk/tools/dsymutil/dsymutil.h +++ llvm/trunk/tools/dsymutil/dsymutil.h @@ -48,6 +48,9 @@ /// Do not check swiftmodule timestamp bool NoTimestamp = false; + /// Number of threads. + unsigned Threads = 1; + /// -oso-prepend-path std::string PrependPath; Index: llvm/trunk/tools/dsymutil/dsymutil.cpp =================================================================== --- llvm/trunk/tools/dsymutil/dsymutil.cpp +++ llvm/trunk/tools/dsymutil/dsymutil.cpp @@ -324,6 +324,11 @@ inconvertibleErrorCode()); } + if (NumThreads == 0) + Options.Threads = llvm::thread::hardware_concurrency(); + if (DumpDebugMap || Verbose) + Options.Threads = 1; + return Options; } @@ -480,12 +485,8 @@ return 1; } - if (NumThreads == 0) - NumThreads = llvm::thread::hardware_concurrency(); - if (DumpDebugMap || Verbose) - NumThreads = 1; - NumThreads = std::min(NumThreads, DebugMapPtrsOrErr->size()); - + NumThreads = + std::min(OptionsOrErr->Threads, DebugMapPtrsOrErr->size()); llvm::ThreadPool Threads(NumThreads); // If there is more than one link to execute, we need to generate