@@ -23,7 +23,7 @@ use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef};
23
23
use llvm:: SMDiagnosticRef ;
24
24
use { CrateTranslation , ModuleSource , ModuleTranslation , CompiledModule , ModuleKind } ;
25
25
use rustc:: hir:: def_id:: CrateNum ;
26
- use rustc:: util:: common:: { time, time_depth, set_time_depth, path2cstr} ;
26
+ use rustc:: util:: common:: { time, time_depth, set_time_depth, path2cstr, print_time_passes_entry } ;
27
27
use rustc:: util:: fs:: { link_or_copy, rename_or_copy_remove} ;
28
28
use errors:: { self , Handler , Level , DiagnosticBuilder , FatalError } ;
29
29
use errors:: emitter:: { Emitter } ;
@@ -44,6 +44,7 @@ use std::str;
44
44
use std:: sync:: Arc ;
45
45
use std:: sync:: mpsc:: { channel, Sender , Receiver } ;
46
46
use std:: slice;
47
+ use std:: time:: Instant ;
47
48
use std:: thread;
48
49
use libc:: { c_uint, c_void, c_char, size_t} ;
49
50
@@ -498,9 +499,9 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
498
499
diag_handler. abort_if_errors ( ) ;
499
500
500
501
// Finally, run the actual optimization passes
501
- time ( config. time_passes , & format ! ( "llvm function passes [{}]" , cgcx . worker ) , ||
502
+ time ( config. time_passes , & format ! ( "llvm function passes [{}]" , module_name . unwrap ( ) ) , ||
502
503
llvm:: LLVMRustRunFunctionPassManager ( fpm, llmod) ) ;
503
- time ( config. time_passes , & format ! ( "llvm module passes [{}]" , cgcx . worker ) , ||
504
+ time ( config. time_passes , & format ! ( "llvm module passes [{}]" , module_name . unwrap ( ) ) , ||
504
505
llvm:: LLVMRunPassManager ( mpm, llmod) ) ;
505
506
506
507
// Deallocate managers that we're now done with
@@ -563,7 +564,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
563
564
llvm:: LLVMWriteBitcodeToFile ( llmod, bc_out_c. as_ptr ( ) ) ;
564
565
}
565
566
566
- time ( config. time_passes , & format ! ( "codegen passes [{}]" , cgcx . worker ) ,
567
+ time ( config. time_passes , & format ! ( "codegen passes [{}]" , module_name . unwrap ( ) ) ,
567
568
|| -> Result < ( ) , FatalError > {
568
569
if config. emit_ir {
569
570
let out = output_names. temp_path ( OutputType :: LlvmAssembly , module_name) ;
@@ -756,6 +757,11 @@ pub fn start_async_translation(sess: &Session,
756
757
metadata_config. set_flags ( sess, no_builtins) ;
757
758
allocator_config. set_flags ( sess, no_builtins) ;
758
759
760
+ // Exclude metadata and allocator modules from time_passes output, since
761
+ // they throw off the "LLVM passes" measurement.
762
+ metadata_config. time_passes = false ;
763
+ allocator_config. time_passes = false ;
764
+
759
765
let client = sess. jobserver_from_env . clone ( ) . unwrap_or_else ( || {
760
766
// Pick a "reasonable maximum" if we don't otherwise have a jobserver in
761
767
// our environment, capping out at 32 so we don't take everything down
@@ -1266,6 +1272,9 @@ fn start_executing_work(sess: &Session,
1266
1272
// manner we can ensure that the maximum number of parallel workers is
1267
1273
// capped at any one point in time.
1268
1274
return thread:: spawn ( move || {
1275
+ // We pretend to be within the top-level LLVM time-passes task here:
1276
+ set_time_depth ( 1 ) ;
1277
+
1269
1278
let max_workers = :: num_cpus:: get ( ) ;
1270
1279
let mut worker_id_counter = 0 ;
1271
1280
let mut free_worker_ids = Vec :: new ( ) ;
@@ -1298,6 +1307,8 @@ fn start_executing_work(sess: &Session,
1298
1307
let mut main_thread_worker_state = MainThreadWorkerState :: Idle ;
1299
1308
let mut running = 0 ;
1300
1309
1310
+ let mut llvm_start_time = None ;
1311
+
1301
1312
// Run the message loop while there's still anything that needs message
1302
1313
// processing:
1303
1314
while !translation_done ||
@@ -1323,6 +1334,7 @@ fn start_executing_work(sess: &Session,
1323
1334
worker : get_worker_id ( & mut free_worker_ids) ,
1324
1335
.. cgcx. clone ( )
1325
1336
} ;
1337
+ maybe_start_llvm_timer ( & item, & mut llvm_start_time) ;
1326
1338
main_thread_worker_state = MainThreadWorkerState :: LLVMing ;
1327
1339
spawn_work ( cgcx, item) ;
1328
1340
}
@@ -1338,7 +1350,7 @@ fn start_executing_work(sess: &Session,
1338
1350
worker : get_worker_id ( & mut free_worker_ids) ,
1339
1351
.. cgcx. clone ( )
1340
1352
} ;
1341
-
1353
+ maybe_start_llvm_timer ( & item , & mut llvm_start_time ) ;
1342
1354
main_thread_worker_state = MainThreadWorkerState :: LLVMing ;
1343
1355
spawn_work ( cgcx, item) ;
1344
1356
}
@@ -1358,6 +1370,8 @@ fn start_executing_work(sess: &Session,
1358
1370
while work_items. len ( ) > 0 && running < tokens. len ( ) {
1359
1371
let ( item, _) = work_items. pop ( ) . unwrap ( ) ;
1360
1372
1373
+ maybe_start_llvm_timer ( & item, & mut llvm_start_time) ;
1374
+
1361
1375
let cgcx = CodegenContext {
1362
1376
worker : get_worker_id ( & mut free_worker_ids) ,
1363
1377
.. cgcx. clone ( )
@@ -1465,6 +1479,16 @@ fn start_executing_work(sess: &Session,
1465
1479
}
1466
1480
}
1467
1481
1482
+ if let Some ( llvm_start_time) = llvm_start_time {
1483
+ let total_llvm_time = Instant :: now ( ) . duration_since ( llvm_start_time) ;
1484
+ // This is the top-level timing for all of LLVM, set the time-depth
1485
+ // to zero.
1486
+ set_time_depth ( 0 ) ;
1487
+ print_time_passes_entry ( cgcx. time_passes ,
1488
+ "LLVM passes" ,
1489
+ total_llvm_time) ;
1490
+ }
1491
+
1468
1492
CompiledModules {
1469
1493
modules : compiled_modules,
1470
1494
metadata_module : compiled_metadata_module. unwrap ( ) ,
@@ -1480,6 +1504,17 @@ fn start_executing_work(sess: &Session,
1480
1504
// Tune me, plz.
1481
1505
items_in_queue >= max_workers. saturating_sub ( workers_running / 2 )
1482
1506
}
1507
+
1508
+ fn maybe_start_llvm_timer ( work_item : & WorkItem ,
1509
+ llvm_start_time : & mut Option < Instant > ) {
1510
+ // We keep track of the -Ztime-passes output manually,
1511
+ // since the closure-based interface does not fit well here.
1512
+ if work_item. config . time_passes {
1513
+ if llvm_start_time. is_none ( ) {
1514
+ * llvm_start_time = Some ( Instant :: now ( ) ) ;
1515
+ }
1516
+ }
1517
+ }
1483
1518
}
1484
1519
1485
1520
pub const TRANS_WORKER_ID : usize = :: std:: usize:: MAX ;
0 commit comments