@@ -1245,37 +1245,20 @@ namespace {
1245
1245
}
1246
1246
};
1247
1247
1248
- struct PMCreator {
1249
- orc::JITTargetMachineBuilder JTMB;
1250
- OptimizationLevel O;
1251
- SmallVector<std::function<void ()>, 0 > &printers;
1252
- PMCreator (TargetMachine &TM, int optlevel, SmallVector<std::function<void ()>, 0 > &printers) JL_NOTSAFEPOINT
1253
- : JTMB(createJTMBFromTM(TM, optlevel)), O(getOptLevel(optlevel)), printers(printers) {}
1254
-
1255
- auto operator ()() JL_NOTSAFEPOINT {
1256
- auto TM = cantFail (JTMB.createTargetMachine ());
1257
- fixupTM (*TM);
1258
- auto NPM = std::make_unique<NewPM>(std::move (TM), O);
1259
- // TODO this needs to be locked, as different resource pools may add to the printer vector at the same time
1260
- printers.push_back ([NPM = NPM.get ()]() JL_NOTSAFEPOINT {
1261
- NPM->printTimers ();
1262
- });
1263
- return NPM;
1264
- }
1265
- };
1266
1248
1267
1249
template <size_t N>
1268
1250
struct OptimizerT {
1269
- OptimizerT (TargetMachine &TM, SmallVector<std::function<void ()>, 0 > &printers) JL_NOTSAFEPOINT {
1251
+ OptimizerT (TargetMachine &TM, SmallSet<std::function<void ()>*, 4 > &printers, std::mutex &print_mutex) JL_NOTSAFEPOINT
1252
+ :TM(TM), printers(printers), print_mutex(print_mutex) {
1270
1253
for (size_t i = 0 ; i < N; i++) {
1271
- PMs[i] = std::make_unique<JuliaOJIT::ResourcePool<std::unique_ptr<PassManager>>>( PMCreator (TM, i, printers ));
1254
+ JTMBs. push_back ( createJTMBFromTM (TM, i));
1272
1255
}
1273
- }
1256
+ }
1274
1257
1275
1258
OptimizerResultT operator ()(orc::ThreadSafeModule TSM, orc::MaterializationResponsibility &R) JL_NOTSAFEPOINT {
1276
1259
TSM.withModuleDo ([&](Module &M) JL_NOTSAFEPOINT {
1277
- auto PoolIdx = cast<ConstantInt>(cast<ConstantAsMetadata>(M.getModuleFlag (" julia.optlevel" ))->getValue ())->getZExtValue ();
1278
- assert (PoolIdx < N && " Invalid optimization pool index" );
1260
+ auto optlevel = cast<ConstantInt>(cast<ConstantAsMetadata>(M.getModuleFlag (" julia.optlevel" ))->getValue ())->getZExtValue ();
1261
+ assert (optlevel < N && " Invalid optimization pool index" );
1279
1262
1280
1263
uint64_t start_time = 0 ;
1281
1264
@@ -1312,7 +1295,22 @@ namespace {
1312
1295
{
1313
1296
JL_TIMING (LLVM_JIT, JIT_Opt);
1314
1297
// Run the optimization
1315
- (****PMs[PoolIdx]).run (M);
1298
+ auto TM = cantFail (JTMBs[optlevel].createTargetMachine ());
1299
+ fixupTM (*TM);
1300
+ NewPM NPM (std::move (TM), getOptLevel (optlevel), M.getContext ());
1301
+ // TODO this needs to be locked, as different resource pools may add to the printer vector at the same time
1302
+ std::function<void ()> printfun = [&]() JL_NOTSAFEPOINT {
1303
+ NPM.printTimers ();
1304
+ };
1305
+ {
1306
+ std::lock_guard<std::mutex> lock (print_mutex);
1307
+ printers.insert (&printfun);
1308
+ }
1309
+ NPM.run (M);
1310
+ {
1311
+ std::lock_guard<std::mutex> lock (print_mutex);
1312
+ printers.erase (&printfun);
1313
+ }
1316
1314
assert (!verifyLLVMIR (M));
1317
1315
}
1318
1316
@@ -1346,7 +1344,7 @@ namespace {
1346
1344
s.dump (stream);
1347
1345
}
1348
1346
ios_printf (stream, " time_ns: %" PRIu64 " \n " , end_time - start_time);
1349
- ios_printf (stream, " optlevel: %d\n " , PoolIdx );
1347
+ ios_printf (stream, " optlevel: %d\n " , optlevel );
1350
1348
1351
1349
// Print LLVM function statistics _after_ optimization
1352
1350
ios_printf (stream, " after: \n " );
@@ -1359,7 +1357,7 @@ namespace {
1359
1357
}
1360
1358
}
1361
1359
++ModulesOptimized;
1362
- switch (PoolIdx ) {
1360
+ switch (optlevel ) {
1363
1361
case 0 :
1364
1362
++OptO0;
1365
1363
break ;
@@ -1380,7 +1378,10 @@ namespace {
1380
1378
return Expected<orc::ThreadSafeModule>{std::move (TSM)};
1381
1379
}
1382
1380
private:
1383
- std::array<std::unique_ptr<JuliaOJIT::ResourcePool<std::unique_ptr<PassManager>>>, N> PMs;
1381
+ TargetMachine &TM;
1382
+ SmallSet<std::function<void ()>*, 4 > &printers;
1383
+ std::mutex &print_mutex;
1384
+ SmallVector<orc::JITTargetMachineBuilder, 4 > JTMBs;
1384
1385
};
1385
1386
1386
1387
template <size_t N>
@@ -1697,7 +1698,7 @@ JuliaOJIT::JuliaOJIT()
1697
1698
LockLayer (ObjectLayer),
1698
1699
CompileLayer (ES, LockLayer, std::make_unique<CompilerT<N_optlevels>>(orc::irManglingOptionsFromTargetOptions (TM->Options ), *TM)),
1699
1700
JITPointersLayer (ES, CompileLayer, orc::IRTransformLayer::TransformFunction (JITPointersT (ES))),
1700
- OptimizeLayer (ES, JITPointersLayer, orc::IRTransformLayer::TransformFunction (OptimizerT<N_optlevels>(*TM, PrintLLVMTimers))),
1701
+ OptimizeLayer (ES, JITPointersLayer, orc::IRTransformLayer::TransformFunction (OptimizerT<N_optlevels>(*TM, PrintLLVMTimers, llvm_printing_mutex ))),
1701
1702
OptSelLayer (ES, OptimizeLayer, orc::IRTransformLayer::TransformFunction (selectOptLevel)),
1702
1703
DepsVerifyLayer (ES, OptSelLayer, orc::IRTransformLayer::TransformFunction (validateExternRelocations)),
1703
1704
ExternalCompileLayer (ES, LockLayer,
@@ -2043,8 +2044,11 @@ size_t JuliaOJIT::getTotalBytes() const
2043
2044
2044
2045
void JuliaOJIT::printTimers ()
2045
2046
{
2046
- for (auto &printer : PrintLLVMTimers) {
2047
- printer ();
2047
+ {
2048
+ std::lock_guard<std::mutex> lock (llvm_printing_mutex);
2049
+ for (auto printer : PrintLLVMTimers) {
2050
+ (*printer)();
2051
+ }
2048
2052
}
2049
2053
reportAndResetTimings ();
2050
2054
}
0 commit comments