Skip to content

Commit a9a0ea9

Browse files
async-llvm(25): Restore -Ztime-passes output for trans and LLVM.
1 parent bd36df8 commit a9a0ea9

File tree

3 files changed

+79
-12
lines changed

3 files changed

+79
-12
lines changed

src/librustc/util/common.rs

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,32 @@ pub fn time<T, F>(do_it: bool, what: &str, f: F) -> T where
5757
let rv = f();
5858
let dur = start.elapsed();
5959

60+
print_time_passes_entry_internal(what, dur);
61+
62+
TIME_DEPTH.with(|slot| slot.set(old));
63+
64+
rv
65+
}
66+
67+
pub fn print_time_passes_entry(do_it: bool, what: &str, dur: Duration) {
68+
if !do_it {
69+
return
70+
}
71+
72+
let old = TIME_DEPTH.with(|slot| {
73+
let r = slot.get();
74+
slot.set(r + 1);
75+
r
76+
});
77+
78+
print_time_passes_entry_internal(what, dur);
79+
80+
TIME_DEPTH.with(|slot| slot.set(old));
81+
}
82+
83+
fn print_time_passes_entry_internal(what: &str, dur: Duration) {
84+
let indentation = TIME_DEPTH.with(|slot| slot.get());
85+
6086
let mem_string = match get_resident() {
6187
Some(n) => {
6288
let mb = n as f64 / 1_000_000.0;
@@ -65,14 +91,10 @@ pub fn time<T, F>(do_it: bool, what: &str, f: F) -> T where
6591
None => "".to_owned(),
6692
};
6793
println!("{}time: {}{}\t{}",
68-
repeat(" ").take(old).collect::<String>(),
94+
repeat(" ").take(indentation).collect::<String>(),
6995
duration_to_secs_str(dur),
7096
mem_string,
7197
what);
72-
73-
TIME_DEPTH.with(|slot| slot.set(old));
74-
75-
rv
7698
}
7799

78100
// Hack up our own formatting for the duration to make it easier for scripts

src/librustc_trans/back/write.rs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef};
2323
use llvm::SMDiagnosticRef;
2424
use {CrateTranslation, ModuleSource, ModuleTranslation, CompiledModule, ModuleKind};
2525
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};
2727
use rustc::util::fs::{link_or_copy, rename_or_copy_remove};
2828
use errors::{self, Handler, Level, DiagnosticBuilder, FatalError};
2929
use errors::emitter::{Emitter};
@@ -44,6 +44,7 @@ use std::str;
4444
use std::sync::Arc;
4545
use std::sync::mpsc::{channel, Sender, Receiver};
4646
use std::slice;
47+
use std::time::Instant;
4748
use std::thread;
4849
use libc::{c_uint, c_void, c_char, size_t};
4950

@@ -498,9 +499,9 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
498499
diag_handler.abort_if_errors();
499500

500501
// 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()), ||
502503
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()), ||
504505
llvm::LLVMRunPassManager(mpm, llmod));
505506

506507
// Deallocate managers that we're now done with
@@ -563,7 +564,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
563564
llvm::LLVMWriteBitcodeToFile(llmod, bc_out_c.as_ptr());
564565
}
565566

566-
time(config.time_passes, &format!("codegen passes [{}]", cgcx.worker),
567+
time(config.time_passes, &format!("codegen passes [{}]", module_name.unwrap()),
567568
|| -> Result<(), FatalError> {
568569
if config.emit_ir {
569570
let out = output_names.temp_path(OutputType::LlvmAssembly, module_name);
@@ -756,6 +757,11 @@ pub fn start_async_translation(sess: &Session,
756757
metadata_config.set_flags(sess, no_builtins);
757758
allocator_config.set_flags(sess, no_builtins);
758759

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+
759765
let client = sess.jobserver_from_env.clone().unwrap_or_else(|| {
760766
// Pick a "reasonable maximum" if we don't otherwise have a jobserver in
761767
// our environment, capping out at 32 so we don't take everything down
@@ -1266,6 +1272,9 @@ fn start_executing_work(sess: &Session,
12661272
// manner we can ensure that the maximum number of parallel workers is
12671273
// capped at any one point in time.
12681274
return thread::spawn(move || {
1275+
// We pretend to be within the top-level LLVM time-passes task here:
1276+
set_time_depth(1);
1277+
12691278
let max_workers = ::num_cpus::get();
12701279
let mut worker_id_counter = 0;
12711280
let mut free_worker_ids = Vec::new();
@@ -1298,6 +1307,8 @@ fn start_executing_work(sess: &Session,
12981307
let mut main_thread_worker_state = MainThreadWorkerState::Idle;
12991308
let mut running = 0;
13001309

1310+
let mut llvm_start_time = None;
1311+
13011312
// Run the message loop while there's still anything that needs message
13021313
// processing:
13031314
while !translation_done ||
@@ -1323,6 +1334,7 @@ fn start_executing_work(sess: &Session,
13231334
worker: get_worker_id(&mut free_worker_ids),
13241335
.. cgcx.clone()
13251336
};
1337+
maybe_start_llvm_timer(&item, &mut llvm_start_time);
13261338
main_thread_worker_state = MainThreadWorkerState::LLVMing;
13271339
spawn_work(cgcx, item);
13281340
}
@@ -1338,7 +1350,7 @@ fn start_executing_work(sess: &Session,
13381350
worker: get_worker_id(&mut free_worker_ids),
13391351
.. cgcx.clone()
13401352
};
1341-
1353+
maybe_start_llvm_timer(&item, &mut llvm_start_time);
13421354
main_thread_worker_state = MainThreadWorkerState::LLVMing;
13431355
spawn_work(cgcx, item);
13441356
}
@@ -1358,6 +1370,8 @@ fn start_executing_work(sess: &Session,
13581370
while work_items.len() > 0 && running < tokens.len() {
13591371
let (item, _) = work_items.pop().unwrap();
13601372

1373+
maybe_start_llvm_timer(&item, &mut llvm_start_time);
1374+
13611375
let cgcx = CodegenContext {
13621376
worker: get_worker_id(&mut free_worker_ids),
13631377
.. cgcx.clone()
@@ -1465,6 +1479,16 @@ fn start_executing_work(sess: &Session,
14651479
}
14661480
}
14671481

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+
14681492
CompiledModules {
14691493
modules: compiled_modules,
14701494
metadata_module: compiled_metadata_module.unwrap(),
@@ -1480,6 +1504,17 @@ fn start_executing_work(sess: &Session,
14801504
// Tune me, plz.
14811505
items_in_queue >= max_workers.saturating_sub(workers_running / 2)
14821506
}
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+
}
14831518
}
14841519

14851520
pub const TRANS_WORKER_ID: usize = ::std::usize::MAX;

src/librustc_trans/base.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ use rustc::ty::{self, Ty, TyCtxt};
4343
use rustc::dep_graph::AssertDepGraphSafe;
4444
use rustc::middle::cstore::LinkMeta;
4545
use rustc::hir::map as hir_map;
46-
use rustc::util::common::time;
46+
use rustc::util::common::{time, print_time_passes_entry};
4747
use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType};
4848
use rustc::session::Session;
4949
use rustc_incremental::{self, IncrementalHashesMap};
@@ -80,7 +80,7 @@ use libc::c_uint;
8080
use std::ffi::{CStr, CString};
8181
use std::str;
8282
use std::sync::Arc;
83-
use std::time::Instant;
83+
use std::time::{Instant, Duration};
8484
use std::i32;
8585
use syntax_pos::Span;
8686
use syntax::attr;
@@ -1093,6 +1093,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
10931093
codegen_units
10941094
};
10951095

1096+
let mut total_trans_time = Duration::new(0, 0);
1097+
10961098
for (cgu_index, cgu) in codegen_units.into_iter().enumerate() {
10971099
ongoing_translation.wait_for_signal_to_translate_item();
10981100
ongoing_translation.check_for_errors(tcx.sess);
@@ -1128,6 +1130,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11281130
let cost = time_to_translate.as_secs() * 1_000_000_000 +
11291131
time_to_translate.subsec_nanos() as u64;
11301132

1133+
total_trans_time += time_to_translate;
1134+
11311135
let is_last_cgu = (cgu_index + 1) == codegen_unit_count;
11321136

11331137
ongoing_translation.submit_translated_module_to_llvm(tcx.sess,
@@ -1137,6 +1141,12 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11371141
ongoing_translation.check_for_errors(tcx.sess);
11381142
}
11391143

1144+
// Since the main thread is sometimes blocked during trans, we keep track
1145+
// -Ztime-passes output manually.
1146+
print_time_passes_entry(tcx.sess.time_passes(),
1147+
"translate to LLVM IR",
1148+
total_trans_time);
1149+
11401150
if let Some(module_dispositions) = module_dispositions {
11411151
assert_module_sources::assert_module_sources(tcx, &module_dispositions);
11421152
}

0 commit comments

Comments
 (0)