async-llvm(11): Delay joining ongoing translation until right before linking.
This commit is contained in:
parent
28589ec3e4
commit
f3ce50558f
@ -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 {
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user