async-llvm(11): Delay joining ongoing translation until right before linking.

This commit is contained in:
Michael Woerister 2017-07-26 11:41:34 +02:00 committed by Michael Woerister
parent 28589ec3e4
commit f3ce50558f
2 changed files with 95 additions and 107 deletions

View File

@ -259,10 +259,10 @@ fn new(sess: &Session, passes: Vec<String>) -> ModuleConfig {
}
}
fn set_flags(&mut self, sess: &Session, trans: &OngoingCrateTranslation) {
fn set_flags(&mut self, sess: &Session, no_builtins: bool) {
self.no_verify = sess.no_verify();
self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes;
self.no_builtins = trans.no_builtins;
self.no_builtins = no_builtins;
self.time_passes = sess.time_passes();
self.inline_threshold = sess.opts.cg.inline_threshold;
self.obj_is_bitcode = sess.target.target.options.obj_is_bitcode;
@ -662,12 +662,21 @@ fn need_crate_bitcode_for_rlib(sess: &Session) -> bool {
}
pub fn run_passes(sess: &Session,
trans: &OngoingCrateTranslation,
modules: Vec<ModuleTranslation>,
metadata_module: ModuleTranslation,
allocator_module: Option<ModuleTranslation>,
output_types: &OutputTypes,
crate_output: &OutputFilenames) {
output_types_override: &OutputTypes,
crate_output: &OutputFilenames,
crate_name: Symbol,
link: LinkMeta,
metadata: EncodedMetadata,
exported_symbols: Arc<ExportedSymbols>,
no_builtins: bool,
windows_subsystem: Option<String>,
linker_info: LinkerInfo,
no_integrated_as: bool)
-> OngoingCrateTranslation {
// It's possible that we have `codegen_units > 1` but only one item in
// `trans.modules`. We could theoretically proceed and do LTO in that
// case, but it would be confusing to have the validity of
@ -732,7 +741,7 @@ pub fn run_passes(sess: &Session,
modules_config.emit_bc = true;
}
for output_type in output_types.keys() {
for output_type in output_types_override.keys() {
match *output_type {
OutputType::Bitcode => { modules_config.emit_bc = true; }
OutputType::LlvmAssembly => { modules_config.emit_ir = true; }
@ -758,9 +767,9 @@ pub fn run_passes(sess: &Session,
}
}
modules_config.set_flags(sess, trans);
metadata_config.set_flags(sess, trans);
allocator_config.set_flags(sess, trans);
modules_config.set_flags(sess, no_builtins);
metadata_config.set_flags(sess, no_builtins);
allocator_config.set_flags(sess, no_builtins);
// Populate a buffer with a list of codegen threads. Items are processed in
@ -797,12 +806,8 @@ pub fn run_passes(sess: &Session,
Client::new(num_workers).expect("failed to create jobserver")
});
drop(modules_config);
drop(metadata_config);
drop(allocator_config);
let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
let (trans_worker_send, trans_worker_receive) = channel();
let (trans_worker_send, _trans_worker_receive) = channel();
let (coordinator_send, coordinator_receive) = channel();
let coordinator_thread = start_executing_work(sess,
@ -812,47 +817,24 @@ pub fn run_passes(sess: &Session,
coordinator_send.clone(),
coordinator_receive,
client,
trans.exported_symbols.clone());
exported_symbols.clone());
for work_item in work_items {
coordinator_send.send(Message::WorkItem(work_item)).unwrap();
}
loop {
shared_emitter_main.check(sess, false);
OngoingCrateTranslation {
crate_name,
link,
metadata,
exported_symbols,
no_builtins,
windows_subsystem,
linker_info,
no_integrated_as,
match trans_worker_receive.recv() {
Err(_) => {
// An `Err` here means that all senders for this channel have
// been closed. This could happen because all work has
// completed successfully or there has been some error.
// At this point we don't care which it is.
break
}
Ok(Message::CheckErrorMessages) => continue,
Ok(msg) => {
bug!("unexpected message {:?}", msg);
}
}
shared_emitter_main,
future: coordinator_thread
}
let compiled_modules = coordinator_thread.join().unwrap();
// Just in case, check this on the way out.
shared_emitter_main.check(sess, false);
sess.diagnostic().abort_if_errors();
copy_module_artifacts_into_incr_comp_cache(sess, &compiled_modules, crate_output);
produce_final_output_artifacts(sess, &compiled_modules, crate_output);
// FIXME: time_llvm_passes support - does this use a global context or
// something?
if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() {
unsafe { llvm::LLVMRustPrintPassTimings(); }
}
*trans.result.borrow_mut() = Some(compiled_modules);
}
fn copy_module_artifacts_into_incr_comp_cache(sess: &Session,
@ -1596,8 +1578,8 @@ pub struct OngoingCrateTranslation {
pub linker_info: LinkerInfo,
pub no_integrated_as: bool,
// This will be replaced by a Future.
pub result: ::std::cell::RefCell<Option<CompiledModules>>,
shared_emitter_main: SharedEmitterMain,
future: thread::JoinHandle<CompiledModules>,
}
impl OngoingCrateTranslation {
@ -1605,8 +1587,19 @@ pub fn join(self,
sess: &Session,
outputs: &OutputFilenames)
-> CrateTranslation {
self.shared_emitter_main.check(sess, true);
let compiled_modules = self.future.join().unwrap();
let result = self.result.borrow_mut().take().unwrap();
sess.abort_if_errors();
copy_module_artifacts_into_incr_comp_cache(sess, &compiled_modules, outputs);
produce_final_output_artifacts(sess, &compiled_modules, outputs);
// FIXME: time_llvm_passes support - does this use a global context or
// something?
if sess.opts.cg.codegen_units == 1 && sess.time_llvm_passes() {
unsafe { llvm::LLVMRustPrintPassTimings(); }
}
let trans = CrateTranslation {
crate_name: self.crate_name,
@ -1617,9 +1610,9 @@ pub fn join(self,
windows_subsystem: self.windows_subsystem,
linker_info: self.linker_info,
modules: result.modules,
metadata_module: result.metadata_module,
allocator_module: result.allocator_module,
modules: compiled_modules.modules,
metadata_module: compiled_modules.metadata_module,
allocator_module: compiled_modules.allocator_module,
};
if self.no_integrated_as {

View File

@ -32,7 +32,7 @@
use back::link;
use back::linker::LinkerInfo;
use back::symbol_export::{self, ExportedSymbols};
use back::write::OngoingCrateTranslation;
use back::write::{self, OngoingCrateTranslation};
use llvm::{ContextRef, Linkage, ModuleRef, ValueRef, Vector, get_param};
use llvm;
use metadata;
@ -963,27 +963,21 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
!tcx.sess.opts.output_types.should_trans() {
let empty_exported_symbols = ExportedSymbols::empty();
let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
let crate_translation = OngoingCrateTranslation {
crate_name: tcx.crate_name(LOCAL_CRATE),
link: link_meta,
metadata: metadata,
exported_symbols: Arc::new(empty_exported_symbols),
no_builtins: no_builtins,
linker_info: linker_info,
windows_subsystem: None,
no_integrated_as: false,
result: ::std::cell::RefCell::new(None),
};
return write::run_passes(tcx.sess,
vec![],
metadata_module,
None,
&output_filenames.outputs,
output_filenames,
::back::write::run_passes(tcx.sess,
&crate_translation,
vec![],
metadata_module,
None,
&output_filenames.outputs,
output_filenames);
return crate_translation;
tcx.crate_name(LOCAL_CRATE),
link_meta,
metadata,
Arc::new(empty_exported_symbols),
no_builtins,
None,
linker_info,
false);
}
let exported_symbols = Arc::new(ExportedSymbols::compute(tcx,
@ -1231,19 +1225,6 @@ fn module_translation<'a, 'tcx>(
(outputs.outputs.contains_key(&OutputType::Object) ||
outputs.outputs.contains_key(&OutputType::Exe)));
let crate_translation = OngoingCrateTranslation {
crate_name: tcx.crate_name(LOCAL_CRATE),
link: link_meta,
metadata: metadata,
exported_symbols,
no_builtins,
linker_info,
windows_subsystem,
no_integrated_as,
result: ::std::cell::RefCell::new(None),
};
time(sess.time_passes(),
"assert dep graph",
|| rustc_incremental::assert_dep_graph(tcx));
@ -1252,34 +1233,48 @@ fn module_translation<'a, 'tcx>(
"serialize dep graph",
|| rustc_incremental::save_dep_graph(tcx,
incremental_hashes_map,
&crate_translation.metadata.hashes,
crate_translation.link.crate_hash));
&metadata.hashes,
link_meta.crate_hash));
// ---
if no_integrated_as {
let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]);
time(sess.time_passes(),
"LLVM passes",
|| ::back::write::run_passes(sess,
&crate_translation,
modules,
metadata_module,
allocator_module,
&output_types,
outputs))
|| write::run_passes(sess,
modules,
metadata_module,
allocator_module,
&output_types,
outputs,
tcx.crate_name(LOCAL_CRATE),
link_meta,
metadata,
exported_symbols,
no_builtins,
windows_subsystem,
linker_info,
no_integrated_as))
} else {
time(sess.time_passes(),
"LLVM passes",
|| ::back::write::run_passes(sess,
&crate_translation,
modules,
metadata_module,
allocator_module,
&sess.opts.output_types,
outputs))
};
|| write::run_passes(sess,
modules,
metadata_module,
allocator_module,
&sess.opts.output_types,
outputs,
crate_translation
tcx.crate_name(LOCAL_CRATE),
link_meta,
metadata,
exported_symbols,
no_builtins,
windows_subsystem,
linker_info,
no_integrated_as))
}
}
#[inline(never)] // give this a place in the profiler