async-llvm(13): Submit LLVM work packages from base::trans_crate().
This commit is contained in:
parent
397b2a800f
commit
b924ec1484
3 changed files with 88 additions and 85 deletions
|
@ -229,7 +229,7 @@ pub fn compile_input(sess: &Session,
|
||||||
sess.code_stats.borrow().print_type_sizes();
|
sess.code_stats.borrow().print_type_sizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans, &outputs);
|
let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans);
|
||||||
|
|
||||||
controller_entry_point!(after_llvm,
|
controller_entry_point!(after_llvm,
|
||||||
sess,
|
sess,
|
||||||
|
@ -1071,10 +1071,9 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
/// Run LLVM itself, producing a bitcode file, assembly file or object file
|
/// Run LLVM itself, producing a bitcode file, assembly file or object file
|
||||||
/// as a side effect.
|
/// as a side effect.
|
||||||
pub fn phase_5_run_llvm_passes(sess: &Session,
|
pub fn phase_5_run_llvm_passes(sess: &Session,
|
||||||
trans: write::OngoingCrateTranslation,
|
trans: write::OngoingCrateTranslation)
|
||||||
outputs: &OutputFilenames)
|
|
||||||
-> (CompileResult, trans::CrateTranslation) {
|
-> (CompileResult, trans::CrateTranslation) {
|
||||||
let trans = trans.join(sess, outputs);
|
let trans = trans.join(sess);
|
||||||
|
|
||||||
if sess.opts.debugging_opts.incremental_info {
|
if sess.opts.debugging_opts.incremental_info {
|
||||||
write::dump_incremental_data(&trans);
|
write::dump_incremental_data(&trans);
|
||||||
|
|
|
@ -662,11 +662,8 @@ fn need_crate_bitcode_for_rlib(sess: &Session) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_passes(sess: &Session,
|
pub fn run_passes(sess: &Session,
|
||||||
modules: Vec<ModuleTranslation>,
|
|
||||||
metadata_module: ModuleTranslation,
|
|
||||||
allocator_module: Option<ModuleTranslation>,
|
|
||||||
crate_output: &OutputFilenames,
|
crate_output: &OutputFilenames,
|
||||||
|
total_work_item_count: usize,
|
||||||
crate_name: Symbol,
|
crate_name: Symbol,
|
||||||
link: LinkMeta,
|
link: LinkMeta,
|
||||||
metadata: EncodedMetadata,
|
metadata: EncodedMetadata,
|
||||||
|
@ -695,12 +692,6 @@ pub fn run_passes(sess: &Session,
|
||||||
sess.opts.output_types.clone()
|
sess.opts.output_types.clone()
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sanity check
|
|
||||||
assert!(modules.len() == sess.opts.cg.codegen_units ||
|
|
||||||
sess.opts.debugging_opts.incremental.is_some() ||
|
|
||||||
!sess.opts.output_types.should_trans() ||
|
|
||||||
sess.opts.debugging_opts.no_trans);
|
|
||||||
|
|
||||||
// Figure out what we actually need to build.
|
// Figure out what we actually need to build.
|
||||||
|
|
||||||
let mut modules_config = ModuleConfig::new(sess, sess.opts.cg.passes.clone());
|
let mut modules_config = ModuleConfig::new(sess, sess.opts.cg.passes.clone());
|
||||||
|
@ -776,38 +767,11 @@ pub fn run_passes(sess: &Session,
|
||||||
metadata_config.set_flags(sess, no_builtins);
|
metadata_config.set_flags(sess, no_builtins);
|
||||||
allocator_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
|
|
||||||
// LIFO order, just because it's a tiny bit simpler that way. (The order
|
|
||||||
// doesn't actually matter.)
|
|
||||||
let mut work_items = Vec::with_capacity(1 + modules.len());
|
|
||||||
|
|
||||||
{
|
|
||||||
let work = build_work_item(metadata_module,
|
|
||||||
metadata_config.clone(sess),
|
|
||||||
crate_output.clone());
|
|
||||||
work_items.push(work);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(allocator) = allocator_module {
|
|
||||||
let work = build_work_item(allocator,
|
|
||||||
allocator_config.clone(sess),
|
|
||||||
crate_output.clone());
|
|
||||||
work_items.push(work);
|
|
||||||
}
|
|
||||||
|
|
||||||
for mtrans in modules {
|
|
||||||
let work = build_work_item(mtrans,
|
|
||||||
modules_config.clone(sess),
|
|
||||||
crate_output.clone());
|
|
||||||
work_items.push(work);
|
|
||||||
}
|
|
||||||
|
|
||||||
let client = sess.jobserver_from_env.clone().unwrap_or_else(|| {
|
let client = sess.jobserver_from_env.clone().unwrap_or_else(|| {
|
||||||
// Pick a "reasonable maximum" if we don't otherwise have a jobserver in
|
// Pick a "reasonable maximum" if we don't otherwise have a jobserver in
|
||||||
// our environment, capping out at 32 so we don't take everything down
|
// our environment, capping out at 32 so we don't take everything down
|
||||||
// by hogging the process run queue.
|
// by hogging the process run queue.
|
||||||
let num_workers = cmp::min(work_items.len() - 1, 32);
|
let num_workers = cmp::min(total_work_item_count - 1, 32);
|
||||||
Client::new(num_workers).expect("failed to create jobserver")
|
Client::new(num_workers).expect("failed to create jobserver")
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -816,16 +780,13 @@ pub fn run_passes(sess: &Session,
|
||||||
let (coordinator_send, coordinator_receive) = channel();
|
let (coordinator_send, coordinator_receive) = channel();
|
||||||
|
|
||||||
let coordinator_thread = start_executing_work(sess,
|
let coordinator_thread = start_executing_work(sess,
|
||||||
work_items.len(),
|
total_work_item_count,
|
||||||
shared_emitter,
|
shared_emitter,
|
||||||
trans_worker_send,
|
trans_worker_send,
|
||||||
coordinator_send.clone(),
|
coordinator_send.clone(),
|
||||||
coordinator_receive,
|
coordinator_receive,
|
||||||
client,
|
client,
|
||||||
exported_symbols.clone());
|
exported_symbols.clone());
|
||||||
for work_item in work_items {
|
|
||||||
coordinator_send.send(Message::WorkItem(work_item)).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
OngoingCrateTranslation {
|
OngoingCrateTranslation {
|
||||||
crate_name,
|
crate_name,
|
||||||
|
@ -837,6 +798,12 @@ pub fn run_passes(sess: &Session,
|
||||||
linker_info,
|
linker_info,
|
||||||
no_integrated_as,
|
no_integrated_as,
|
||||||
|
|
||||||
|
regular_module_config: modules_config,
|
||||||
|
metadata_module_config: metadata_config,
|
||||||
|
allocator_module_config: allocator_config,
|
||||||
|
|
||||||
|
output_filenames: crate_output.clone(),
|
||||||
|
coordinator_send,
|
||||||
shared_emitter_main,
|
shared_emitter_main,
|
||||||
future: coordinator_thread
|
future: coordinator_thread
|
||||||
}
|
}
|
||||||
|
@ -1583,22 +1550,29 @@ pub struct OngoingCrateTranslation {
|
||||||
pub linker_info: LinkerInfo,
|
pub linker_info: LinkerInfo,
|
||||||
pub no_integrated_as: bool,
|
pub no_integrated_as: bool,
|
||||||
|
|
||||||
|
output_filenames: OutputFilenames,
|
||||||
|
regular_module_config: ModuleConfig,
|
||||||
|
metadata_module_config: ModuleConfig,
|
||||||
|
allocator_module_config: ModuleConfig,
|
||||||
|
|
||||||
|
coordinator_send: Sender<Message>,
|
||||||
shared_emitter_main: SharedEmitterMain,
|
shared_emitter_main: SharedEmitterMain,
|
||||||
future: thread::JoinHandle<CompiledModules>,
|
future: thread::JoinHandle<CompiledModules>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OngoingCrateTranslation {
|
impl OngoingCrateTranslation {
|
||||||
pub fn join(self,
|
pub fn join(self, sess: &Session) -> CrateTranslation {
|
||||||
sess: &Session,
|
|
||||||
outputs: &OutputFilenames)
|
|
||||||
-> CrateTranslation {
|
|
||||||
self.shared_emitter_main.check(sess, true);
|
self.shared_emitter_main.check(sess, true);
|
||||||
let compiled_modules = self.future.join().unwrap();
|
let compiled_modules = self.future.join().unwrap();
|
||||||
|
|
||||||
sess.abort_if_errors();
|
sess.abort_if_errors();
|
||||||
|
|
||||||
copy_module_artifacts_into_incr_comp_cache(sess, &compiled_modules, outputs);
|
copy_module_artifacts_into_incr_comp_cache(sess,
|
||||||
produce_final_output_artifacts(sess, &compiled_modules, outputs);
|
&compiled_modules,
|
||||||
|
&self.output_filenames);
|
||||||
|
produce_final_output_artifacts(sess,
|
||||||
|
&compiled_modules,
|
||||||
|
&self.output_filenames);
|
||||||
|
|
||||||
// FIXME: time_llvm_passes support - does this use a global context or
|
// FIXME: time_llvm_passes support - does this use a global context or
|
||||||
// something?
|
// something?
|
||||||
|
@ -1621,24 +1595,41 @@ impl OngoingCrateTranslation {
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.no_integrated_as {
|
if self.no_integrated_as {
|
||||||
run_assembler(sess, outputs);
|
run_assembler(sess, &self.output_filenames);
|
||||||
|
|
||||||
// HACK the linker expects the object file to be named foo.0.o but
|
// HACK the linker expects the object file to be named foo.0.o but
|
||||||
// `run_assembler` produces an object named just foo.o. Rename it if we
|
// `run_assembler` produces an object named just foo.o. Rename it if we
|
||||||
// are going to build an executable
|
// are going to build an executable
|
||||||
if sess.opts.output_types.contains_key(&OutputType::Exe) {
|
if sess.opts.output_types.contains_key(&OutputType::Exe) {
|
||||||
let f = outputs.path(OutputType::Object);
|
let f = self.output_filenames.path(OutputType::Object);
|
||||||
rename_or_copy_remove(&f,
|
rename_or_copy_remove(&f,
|
||||||
f.with_file_name(format!("{}.0.o",
|
f.with_file_name(format!("{}.0.o",
|
||||||
f.file_stem().unwrap().to_string_lossy()))).unwrap();
|
f.file_stem().unwrap().to_string_lossy()))).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove assembly source, unless --save-temps was specified
|
// Remove assembly source, unless --save-temps was specified
|
||||||
if !sess.opts.cg.save_temps {
|
if !sess.opts.cg.save_temps {
|
||||||
fs::remove_file(&outputs.temp_path(OutputType::Assembly, None)).unwrap();
|
fs::remove_file(&self.output_filenames
|
||||||
|
.temp_path(OutputType::Assembly, None)).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trans
|
trans
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn submit_translated_module_to_llvm(&self,
|
||||||
|
sess: &Session,
|
||||||
|
mtrans: ModuleTranslation) {
|
||||||
|
let module_config = match mtrans.kind {
|
||||||
|
ModuleKind::Regular => self.regular_module_config.clone(sess),
|
||||||
|
ModuleKind::Metadata => self.metadata_module_config.clone(sess),
|
||||||
|
ModuleKind::Allocator => self.allocator_module_config.clone(sess),
|
||||||
|
};
|
||||||
|
|
||||||
|
let work_item = build_work_item(mtrans,
|
||||||
|
module_config,
|
||||||
|
self.output_filenames.clone());
|
||||||
|
|
||||||
|
drop(self.coordinator_send.send(Message::WorkItem(work_item)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -963,20 +963,22 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
!tcx.sess.opts.output_types.should_trans() {
|
!tcx.sess.opts.output_types.should_trans() {
|
||||||
let empty_exported_symbols = ExportedSymbols::empty();
|
let empty_exported_symbols = ExportedSymbols::empty();
|
||||||
let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
|
let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
|
||||||
return write::run_passes(tcx.sess,
|
let ongoing_translation = write::run_passes(
|
||||||
vec![],
|
tcx.sess,
|
||||||
metadata_module,
|
output_filenames,
|
||||||
None,
|
1,
|
||||||
output_filenames,
|
tcx.crate_name(LOCAL_CRATE),
|
||||||
|
link_meta,
|
||||||
|
metadata,
|
||||||
|
Arc::new(empty_exported_symbols),
|
||||||
|
no_builtins,
|
||||||
|
None,
|
||||||
|
linker_info,
|
||||||
|
false);
|
||||||
|
|
||||||
tcx.crate_name(LOCAL_CRATE),
|
ongoing_translation.submit_translated_module_to_llvm(tcx.sess, metadata_module);
|
||||||
link_meta,
|
|
||||||
metadata,
|
return ongoing_translation;
|
||||||
Arc::new(empty_exported_symbols),
|
|
||||||
no_builtins,
|
|
||||||
None,
|
|
||||||
linker_info,
|
|
||||||
false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let exported_symbols = Arc::new(ExportedSymbols::compute(tcx,
|
let exported_symbols = Arc::new(ExportedSymbols::compute(tcx,
|
||||||
|
@ -1236,22 +1238,33 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
link_meta.crate_hash));
|
link_meta.crate_hash));
|
||||||
// ---
|
// ---
|
||||||
|
|
||||||
time(sess.time_passes(),
|
let total_module_count = modules.len() + 1 +
|
||||||
"LLVM passes",
|
if allocator_module.is_some() { 1 } else { 0 };
|
||||||
|| write::run_passes(sess,
|
|
||||||
modules,
|
|
||||||
metadata_module,
|
|
||||||
allocator_module,
|
|
||||||
outputs,
|
|
||||||
|
|
||||||
tcx.crate_name(LOCAL_CRATE),
|
let ongoing_translation = write::run_passes(
|
||||||
link_meta,
|
sess,
|
||||||
metadata,
|
outputs,
|
||||||
exported_symbols,
|
total_module_count,
|
||||||
no_builtins,
|
tcx.crate_name(LOCAL_CRATE),
|
||||||
windows_subsystem,
|
link_meta,
|
||||||
linker_info,
|
metadata,
|
||||||
no_integrated_as))
|
exported_symbols,
|
||||||
|
no_builtins,
|
||||||
|
windows_subsystem,
|
||||||
|
linker_info,
|
||||||
|
no_integrated_as);
|
||||||
|
|
||||||
|
ongoing_translation.submit_translated_module_to_llvm(sess, metadata_module);
|
||||||
|
|
||||||
|
for mtrans in modules {
|
||||||
|
ongoing_translation.submit_translated_module_to_llvm(sess, mtrans);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(allocator_module) = allocator_module {
|
||||||
|
ongoing_translation.submit_translated_module_to_llvm(sess, allocator_module);
|
||||||
|
}
|
||||||
|
|
||||||
|
ongoing_translation
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(never)] // give this a place in the profiler
|
#[inline(never)] // give this a place in the profiler
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue