diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index bae50da3209..c33d65e3e53 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -259,10 +259,10 @@ impl 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, metadata_module: ModuleTranslation, allocator_module: Option, - output_types: &OutputTypes, - crate_output: &OutputFilenames) { + output_types_override: &OutputTypes, + crate_output: &OutputFilenames, + + crate_name: Symbol, + link: LinkMeta, + metadata: EncodedMetadata, + exported_symbols: Arc, + no_builtins: bool, + windows_subsystem: Option, + 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>, + shared_emitter_main: SharedEmitterMain, + future: thread::JoinHandle, } impl OngoingCrateTranslation { @@ -1605,8 +1587,19 @@ impl OngoingCrateTranslation { 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 @@ impl OngoingCrateTranslation { 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 { diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 6eb38dc52ee..65041e60fe3 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -32,7 +32,7 @@ use assert_module_sources; 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 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, '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 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, '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