Skip to content

Commit b4e44cb

Browse files
authored
Merge pull request #23786 from aschwaighofer/increase_stack_limit_threads-5.0
[5.0] Increase the stack size limit for running llvm codegen threads …
2 parents a13f412 + e97ed4a commit b4e44cb

File tree

1 file changed

+107
-28
lines changed

1 file changed

+107
-28
lines changed

lib/IRGen/IRGen.cpp

Lines changed: 107 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -870,26 +870,109 @@ performIRGeneration(IRGenOptions &Opts, ModuleDecl *M,
870870
return std::unique_ptr<llvm::Module>(IGM.releaseModule());
871871
}
872872

873-
static void ThreadEntryPoint(IRGenerator *irgen,
874-
llvm::sys::Mutex *DiagMutex, int ThreadIdx) {
875-
while (IRGenModule *IGM = irgen->fetchFromQueue()) {
876-
LLVM_DEBUG(DiagMutex->lock(); dbgs() << "thread " << ThreadIdx
877-
<< ": fetched "
878-
<< IGM->OutputFilename << "\n";
879-
DiagMutex->unlock(););
880-
embedBitcode(IGM->getModule(), irgen->Opts);
881-
performLLVM(irgen->Opts, &IGM->Context.Diags, DiagMutex, IGM->ModuleHash,
882-
IGM->getModule(), IGM->TargetMachine.get(),
883-
IGM->Context.LangOpts.EffectiveLanguageVersion,
884-
IGM->OutputFilename, IGM->Context.Stats);
885-
if (IGM->Context.Diags.hadAnyError())
873+
namespace {
874+
struct LLVMCodeGenThreads {
875+
876+
struct Thread {
877+
LLVMCodeGenThreads &parent;
878+
unsigned threadIndex;
879+
#ifdef __APPLE__
880+
pthread_t threadId;
881+
#else
882+
std::thread *thread;
883+
#endif
884+
885+
Thread(LLVMCodeGenThreads &parent, unsigned threadIndex)
886+
: parent(parent), threadIndex(threadIndex)
887+
#ifndef __APPLE__
888+
, thread(nullptr)
889+
#endif
890+
{}
891+
892+
/// Run llvm codegen.
893+
void run() {
894+
auto *diagMutex = parent.diagMutex;
895+
while (IRGenModule *IGM = parent.irgen->fetchFromQueue()) {
896+
LLVM_DEBUG(diagMutex->lock();
897+
dbgs() << "thread " << threadIndex << ": fetched "
898+
<< IGM->OutputFilename << "\n";
899+
diagMutex->unlock(););
900+
embedBitcode(IGM->getModule(), parent.irgen->Opts);
901+
performLLVM(parent.irgen->Opts, &IGM->Context.Diags, diagMutex,
902+
IGM->ModuleHash, IGM->getModule(), IGM->TargetMachine.get(),
903+
IGM->Context.LangOpts.EffectiveLanguageVersion,
904+
IGM->OutputFilename, IGM->Context.Stats);
905+
if (IGM->Context.Diags.hadAnyError())
906+
return;
907+
}
908+
LLVM_DEBUG(diagMutex->lock();
909+
dbgs() << "thread " << threadIndex << ": done\n";
910+
diagMutex->unlock(););
886911
return;
912+
}
913+
};
914+
915+
IRGenerator *irgen;
916+
llvm::sys::Mutex *diagMutex;
917+
std::vector<Thread> threads;
918+
919+
LLVMCodeGenThreads(IRGenerator *irgen, llvm::sys::Mutex *diagMutex,
920+
unsigned numThreads)
921+
: irgen(irgen), diagMutex(diagMutex) {
922+
threads.reserve(numThreads);
923+
for (unsigned idx = 0; idx < numThreads; ++idx) {
924+
// the 0-th thread is executed by the main thread.
925+
threads.push_back(Thread(*this, idx + 1));
926+
}
927+
}
928+
929+
static void *runThread(void *arg) {
930+
auto *thread = reinterpret_cast<Thread *>(arg);
931+
thread->run();
932+
return nullptr;
933+
}
934+
935+
void startThreads() {
936+
#ifdef __APPLE__
937+
// Increase the thread stack size on macosx to 8MB (default is 512KB). This
938+
// matches the main thread.
939+
pthread_attr_t stackSizeAttribute;
940+
int err = pthread_attr_init(&stackSizeAttribute);
941+
assert(!err);
942+
err = pthread_attr_setstacksize(&stackSizeAttribute, 8 * 1024 * 1024);
943+
assert(!err);
944+
945+
for (auto &thread : threads) {
946+
pthread_create(&thread.threadId, &stackSizeAttribute,
947+
LLVMCodeGenThreads::runThread, &thread);
948+
}
949+
950+
pthread_attr_destroy(&stackSizeAttribute);
951+
#else
952+
for (auto &thread : threads) {
953+
thread.thread = new std::thread(runThread, &thread);
954+
}
955+
#endif
956+
957+
}
958+
959+
void runMainThread() {
960+
Thread mainThread(*this, 0);
961+
mainThread.run();
887962
}
888-
LLVM_DEBUG(
889-
DiagMutex->lock();
890-
dbgs() << "thread " << ThreadIdx << ": done\n";
891-
DiagMutex->unlock();
892-
);
963+
964+
void join() {
965+
#ifdef __APPLE__
966+
for (auto &thread : threads)
967+
pthread_join(thread.threadId, 0);
968+
#else
969+
for (auto &thread: threads) {
970+
thread.thread->join();
971+
delete thread.thread;
972+
}
973+
#endif
974+
}
975+
};
893976
}
894977

895978
/// Generates LLVM IR, runs the LLVM passes and produces the output files.
@@ -1068,26 +1151,22 @@ static void performParallelIRGeneration(
10681151

10691152
SharedTimer timer("LLVM pipeline");
10701153

1071-
std::vector<std::thread> Threads;
10721154
llvm::sys::Mutex DiagMutex;
10731155

10741156
// Start all the threads and do the LLVM compilation.
1075-
for (int ThreadIdx = 1; ThreadIdx < numThreads; ++ThreadIdx) {
1076-
Threads.push_back(std::thread(ThreadEntryPoint, &irgen, &DiagMutex,
1077-
ThreadIdx));
1078-
}
1157+
LLVMCodeGenThreads codeGenThreads(&irgen, &DiagMutex, numThreads - 1);
1158+
codeGenThreads.startThreads();
10791159

10801160
// Free the memory occupied by the SILModule.
10811161
// Execute this task in parallel to the LLVM compilation.
10821162
auto SILModuleRelease = [&SILMod]() { SILMod.reset(nullptr); };
1083-
Threads.push_back(std::thread(SILModuleRelease));
1163+
auto releaseModuleThread = std::thread(SILModuleRelease);
10841164

1085-
ThreadEntryPoint(&irgen, &DiagMutex, 0);
1165+
codeGenThreads.runMainThread();
10861166

10871167
// Wait for all threads.
1088-
for (std::thread &Thread : Threads) {
1089-
Thread.join();
1090-
}
1168+
releaseModuleThread.join();
1169+
codeGenThreads.join();
10911170
}
10921171

10931172
std::unique_ptr<llvm::Module> swift::performIRGeneration(

0 commit comments

Comments
 (0)