@@ -91,6 +91,10 @@ static cl::list<std::string> InputFiles(cl::Positional, cl::OneOrMore,
91
91
cl::desc (" input files" ),
92
92
cl::cat(JITLinkCategory));
93
93
94
+ static cl::opt<size_t > MaterializationThreads (
95
+ " num-threads" , cl::desc(" Number of materialization threads to use" ),
96
+ cl::init(std::numeric_limits<size_t >::max()), cl::cat(JITLinkCategory));
97
+
94
98
static cl::list<std::string>
95
99
LibrarySearchPaths (" L" ,
96
100
cl::desc (" Add dir to the list of library search paths" ),
@@ -400,6 +404,7 @@ bool lazyLinkingRequested() {
400
404
}
401
405
402
406
static Error applyHarnessPromotions (Session &S, LinkGraph &G) {
407
+ std::lock_guard<std::mutex> Lock (S.M );
403
408
404
409
// If this graph is part of the test harness there's nothing to do.
405
410
if (S.HarnessFiles .empty () || S.HarnessFiles .count (G.getName ()))
@@ -450,7 +455,11 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
450
455
return Error::success ();
451
456
}
452
457
453
- static void dumpSectionContents (raw_ostream &OS, LinkGraph &G) {
458
+ static void dumpSectionContents (raw_ostream &OS, Session &S, LinkGraph &G) {
459
+ std::lock_guard<std::mutex> Lock (S.M );
460
+
461
+ outs () << " Relocated section contents for " << G.getName () << " :\n " ;
462
+
454
463
constexpr orc::ExecutorAddrDiff DumpWidth = 16 ;
455
464
static_assert (isPowerOf2_64 (DumpWidth), " DumpWidth must be a power of two" );
456
465
@@ -842,7 +851,7 @@ static Expected<std::unique_ptr<ExecutorProcessControl>> launchExecutor() {
842
851
S.CreateMemoryManager = createSharedMemoryManager;
843
852
844
853
return SimpleRemoteEPC::Create<FDSimpleRemoteEPCTransport>(
845
- std::make_unique<DynamicThreadPoolTaskDispatcher>(std::nullopt ),
854
+ std::make_unique<DynamicThreadPoolTaskDispatcher>(MaterializationThreads ),
846
855
std::move (S), FromExecutor[ReadEnd], ToExecutor[WriteEnd]);
847
856
#endif
848
857
}
@@ -984,10 +993,16 @@ Expected<std::unique_ptr<Session>> Session::Create(Triple TT,
984
993
auto PageSize = sys::Process::getPageSize ();
985
994
if (!PageSize)
986
995
return PageSize.takeError ();
996
+ std::unique_ptr<TaskDispatcher> Dispatcher;
997
+ if (MaterializationThreads == 0 )
998
+ Dispatcher = std::make_unique<InPlaceTaskDispatcher>();
999
+ else
1000
+ Dispatcher = std::make_unique<DynamicThreadPoolTaskDispatcher>(
1001
+ MaterializationThreads);
1002
+
987
1003
EPC = std::make_unique<SelfExecutorProcessControl>(
988
- std::make_shared<SymbolStringPool>(),
989
- std::make_unique<InPlaceTaskDispatcher>(), std::move (TT), *PageSize,
990
- createInProcessMemoryManager ());
1004
+ std::make_shared<SymbolStringPool>(), std::move (Dispatcher),
1005
+ std::move (TT), *PageSize, createInProcessMemoryManager ());
991
1006
}
992
1007
993
1008
Error Err = Error::success ();
@@ -1221,6 +1236,7 @@ void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) {
1221
1236
1222
1237
if (ShowGraphsRegex)
1223
1238
PassConfig.PostFixupPasses .push_back ([this ](LinkGraph &G) -> Error {
1239
+ std::lock_guard<std::mutex> Lock (M);
1224
1240
// Print graph if ShowLinkGraphs is specified-but-empty, or if
1225
1241
// it contains the given graph.
1226
1242
if (ShowGraphsRegex->match (G.getName ())) {
@@ -1239,9 +1255,8 @@ void Session::modifyPassConfig(LinkGraph &G, PassConfiguration &PassConfig) {
1239
1255
[this ](LinkGraph &G) { return applyHarnessPromotions (*this , G); });
1240
1256
1241
1257
if (ShowRelocatedSectionContents)
1242
- PassConfig.PostFixupPasses .push_back ([](LinkGraph &G) -> Error {
1243
- outs () << " Relocated section contents for " << G.getName () << " :\n " ;
1244
- dumpSectionContents (outs (), G);
1258
+ PassConfig.PostFixupPasses .push_back ([this ](LinkGraph &G) -> Error {
1259
+ dumpSectionContents (outs (), *this , G);
1245
1260
return Error::success ();
1246
1261
});
1247
1262
@@ -1613,6 +1628,31 @@ static Error sanitizeArguments(const Triple &TT, const char *ArgV0) {
1613
1628
}
1614
1629
}
1615
1630
1631
+ if (MaterializationThreads == std::numeric_limits<size_t >::max ()) {
1632
+ if (auto HC = std::thread::hardware_concurrency ())
1633
+ MaterializationThreads = HC;
1634
+ else {
1635
+ errs () << " Warning: std::thread::hardware_concurrency() returned 0, "
1636
+ " defaulting to -threads=1.\n " ;
1637
+ MaterializationThreads = 1 ;
1638
+ }
1639
+ }
1640
+
1641
+ if (!!OutOfProcessExecutor.getNumOccurrences () ||
1642
+ !!OutOfProcessExecutorConnect.getNumOccurrences ()) {
1643
+ if (NoExec)
1644
+ return make_error<StringError>(" -noexec cannot be used with " +
1645
+ OutOfProcessExecutor.ArgStr + " or " +
1646
+ OutOfProcessExecutorConnect.ArgStr ,
1647
+ inconvertibleErrorCode ());
1648
+
1649
+ if (MaterializationThreads == 0 )
1650
+ return make_error<StringError>(" -threads=0 cannot be used with " +
1651
+ OutOfProcessExecutor.ArgStr + " or " +
1652
+ OutOfProcessExecutorConnect.ArgStr ,
1653
+ inconvertibleErrorCode ());
1654
+ }
1655
+
1616
1656
// Only one of -oop-executor and -oop-executor-connect can be used.
1617
1657
if (!!OutOfProcessExecutor.getNumOccurrences () &&
1618
1658
!!OutOfProcessExecutorConnect.getNumOccurrences ())
0 commit comments