@@ -667,6 +667,37 @@ Error LLJITBuilderState::prepareForConstruction() {
667
667
return JTMBOrErr.takeError ();
668
668
}
669
669
670
+ if ((ES || EPC) && NumCompileThreads)
671
+ return make_error<StringError>(
672
+ " NumCompileThreads cannot be used with a custom ExecutionSession or "
673
+ " ExecutorProcessControl" ,
674
+ inconvertibleErrorCode ());
675
+
676
+ #if !LLVM_ENABLE_THREADS
677
+ if (NumCompileThreads)
678
+ return make_error<StringError>(
679
+ " LLJIT num-compile-threads is " + Twine (NumCompileThreads) +
680
+ " but LLVM was compiled with LLVM_ENABLE_THREADS=Off" ,
681
+ inconvertibleErrorCode ());
682
+ #endif // !LLVM_ENABLE_THREADS
683
+
684
+ bool ConcurrentCompilationSettingDefaulted = !SupportConcurrentCompilation;
685
+ if (!SupportConcurrentCompilation) {
686
+ #if LLVM_ENABLE_THREADS
687
+ SupportConcurrentCompilation = NumCompileThreads || ES || EPC;
688
+ #else
689
+ SupportConcurrentCompilation = false ;
690
+ #endif // LLVM_ENABLE_THREADS
691
+ } else {
692
+ #if !LLVM_ENABLE_THREADS
693
+ if (*SupportConcurrentCompilation)
694
+ return make_error<StringError>(
695
+ " LLJIT concurrent compilation support requested, but LLVM was built "
696
+ " with LLVM_ENABLE_THREADS=Off" ,
697
+ inconvertibleErrorCode ());
698
+ #endif // !LLVM_ENABLE_THREADS
699
+ }
700
+
670
701
LLVM_DEBUG ({
671
702
dbgs () << " JITTargetMachineBuilder is "
672
703
<< JITTargetMachineBuilderPrinter (*JTMB, " " )
@@ -684,11 +715,13 @@ Error LLJITBuilderState::prepareForConstruction() {
684
715
<< (CreateCompileFunction ? " Yes" : " No" ) << " \n "
685
716
<< " Custom platform-setup function: "
686
717
<< (SetUpPlatform ? " Yes" : " No" ) << " \n "
687
- << " Number of compile threads: " << NumCompileThreads;
688
- if (!NumCompileThreads)
689
- dbgs () << " (code will be compiled on the execution thread)\n " ;
718
+ << " Support concurrent compilation: "
719
+ << (*SupportConcurrentCompilation ? " Yes" : " No" );
720
+ if (ConcurrentCompilationSettingDefaulted)
721
+ dbgs () << " (defaulted based on ES / EPC)\n " ;
690
722
else
691
723
dbgs () << " \n " ;
724
+ dbgs () << " Number of compile threads: " << NumCompileThreads << " \n " ;
692
725
});
693
726
694
727
// Create DL if not specified.
@@ -705,7 +738,19 @@ Error LLJITBuilderState::prepareForConstruction() {
705
738
dbgs () << " ExecutorProcessControl not specified, "
706
739
" Creating SelfExecutorProcessControl instance\n " ;
707
740
});
708
- if (auto EPCOrErr = SelfExecutorProcessControl::Create ())
741
+
742
+ std::unique_ptr<TaskDispatcher> D = nullptr ;
743
+ #if LLVM_ENABLE_THREADS
744
+ if (*SupportConcurrentCompilation) {
745
+ std::optional<size_t > NumThreads = std ::nullopt;
746
+ if (NumCompileThreads)
747
+ NumThreads = NumCompileThreads;
748
+ D = std::make_unique<DynamicThreadPoolTaskDispatcher>(NumThreads);
749
+ } else
750
+ D = std::make_unique<InPlaceTaskDispatcher>();
751
+ #endif // LLVM_ENABLE_THREADS
752
+ if (auto EPCOrErr =
753
+ SelfExecutorProcessControl::Create (nullptr , std::move (D), nullptr ))
709
754
EPC = std::move (*EPCOrErr);
710
755
else
711
756
return EPCOrErr.takeError ();
@@ -790,8 +835,6 @@ Error LLJITBuilderState::prepareForConstruction() {
790
835
}
791
836
792
837
LLJIT::~LLJIT () {
793
- if (CompileThreads)
794
- CompileThreads->wait ();
795
838
if (auto Err = ES->endSession ())
796
839
ES->reportError (std::move (Err));
797
840
}
@@ -916,9 +959,8 @@ LLJIT::createCompileFunction(LLJITBuilderState &S,
916
959
if (S.CreateCompileFunction )
917
960
return S.CreateCompileFunction (std::move (JTMB));
918
961
919
- // Otherwise default to creating a SimpleCompiler, or ConcurrentIRCompiler,
920
- // depending on the number of threads requested.
921
- if (S.NumCompileThreads > 0 )
962
+ // If using a custom EPC then use a ConcurrentIRCompiler by default.
963
+ if (*S.SupportConcurrentCompilation )
922
964
return std::make_unique<ConcurrentIRCompiler>(std::move (JTMB));
923
965
924
966
auto TM = JTMB.createTargetMachine ();
@@ -970,21 +1012,8 @@ LLJIT::LLJIT(LLJITBuilderState &S, Error &Err)
970
1012
std::make_unique<IRTransformLayer>(*ES, *TransformLayer);
971
1013
}
972
1014
973
- if (S. NumCompileThreads > 0 ) {
1015
+ if (*S. SupportConcurrentCompilation )
974
1016
InitHelperTransformLayer->setCloneToNewContextOnEmit (true );
975
- CompileThreads = std::make_unique<DefaultThreadPool>(
976
- hardware_concurrency (S.NumCompileThreads ));
977
- ES->setDispatchTask ([this ](std::unique_ptr<Task> T) {
978
- // FIXME: We should be able to use move-capture here, but ThreadPool's
979
- // AsyncTaskTys are std::functions rather than unique_functions
980
- // (because MSVC's std::packaged_tasks don't support move-only types).
981
- // Fix this when all the above gets sorted out.
982
- CompileThreads->async ([UnownedT = T.release ()]() mutable {
983
- std::unique_ptr<Task> T (UnownedT);
984
- T->run ();
985
- });
986
- });
987
- }
988
1017
989
1018
if (S.SetupProcessSymbolsJITDylib ) {
990
1019
if (auto ProcSymsJD = S.SetupProcessSymbolsJITDylib (*this )) {
@@ -1240,7 +1269,7 @@ LLLazyJIT::LLLazyJIT(LLLazyJITBuilderState &S, Error &Err) : LLJIT(S, Err) {
1240
1269
CODLayer = std::make_unique<CompileOnDemandLayer>(
1241
1270
*ES, *InitHelperTransformLayer, *LCTMgr, std::move (ISMBuilder));
1242
1271
1243
- if (S. NumCompileThreads > 0 )
1272
+ if (*S. SupportConcurrentCompilation )
1244
1273
CODLayer->setCloneToNewContextOnEmit (true );
1245
1274
}
1246
1275
0 commit comments