Skip to content

Commit f45758c

Browse files
committed
Compile some CGUs in parallel at the start of codegen
1 parent 59eb49d commit f45758c

File tree

4 files changed

+61
-21
lines changed

4 files changed

+61
-21
lines changed

src/librustc_codegen_llvm/base.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
//! but one `llvm::Type` corresponds to many `Ty`s; for instance, `tup(int, int,
1414
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
1515
16-
use super::{LlvmCodegenBackend, ModuleLlvm};
16+
use super::ModuleLlvm;
1717

1818
use crate::builder::Builder;
1919
use crate::common;
@@ -29,7 +29,6 @@ use rustc::middle::exported_symbols;
2929
use rustc::mir::mono::{Linkage, Visibility};
3030
use rustc::session::config::DebugInfo;
3131
use rustc::ty::TyCtxt;
32-
use rustc_codegen_ssa::back::write::submit_codegened_module_to_llvm;
3332
use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
3433
use rustc_codegen_ssa::mono_item::MonoItemExt;
3534
use rustc_codegen_ssa::traits::*;
@@ -100,8 +99,7 @@ pub fn iter_globals(llmod: &'ll llvm::Module) -> ValueIter<'ll> {
10099
pub fn compile_codegen_unit(
101100
tcx: TyCtxt<'tcx>,
102101
cgu_name: Symbol,
103-
tx_to_llvm_workers: &std::sync::mpsc::Sender<Box<dyn std::any::Any + Send>>,
104-
) {
102+
) -> (ModuleCodegen<ModuleLlvm>, u64) {
105103
let prof_timer = tcx.prof.generic_activity("codegen_module");
106104
let start_time = Instant::now();
107105

@@ -115,8 +113,6 @@ pub fn compile_codegen_unit(
115113
// the time we needed for codegenning it.
116114
let cost = time_to_codegen.as_secs() * 1_000_000_000 + time_to_codegen.subsec_nanos() as u64;
117115

118-
submit_codegened_module_to_llvm(&LlvmCodegenBackend(()), tx_to_llvm_workers, module, cost);
119-
120116
fn module_codegen(tcx: TyCtxt<'_>, cgu_name: Symbol) -> ModuleCodegen<ModuleLlvm> {
121117
let cgu = tcx.codegen_unit(cgu_name);
122118
// Instantiate monomorphizations without filling out definitions yet...
@@ -164,6 +160,8 @@ pub fn compile_codegen_unit(
164160
kind: ModuleKind::Regular,
165161
}
166162
}
163+
164+
(module, cost)
167165
}
168166

169167
pub fn set_link_section(llval: &Value, attrs: &CodegenFnAttrs) {

src/librustc_codegen_llvm/lib.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#![feature(link_args)]
2020
#![feature(static_nobundle)]
2121
#![feature(trusted_len)]
22+
#![recursion_limit = "256"]
2223

2324
use back::write::{create_informational_target_machine, create_target_machine};
2425
use rustc_span::symbol::Symbol;
@@ -108,9 +109,8 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
108109
&self,
109110
tcx: TyCtxt<'_>,
110111
cgu_name: Symbol,
111-
tx: &std::sync::mpsc::Sender<Box<dyn Any + Send>>,
112-
) {
113-
base::compile_codegen_unit(tcx, cgu_name, tx);
112+
) -> (ModuleCodegen<ModuleLlvm>, u64) {
113+
base::compile_codegen_unit(tcx, cgu_name)
114114
}
115115
fn target_machine_factory(
116116
&self,

src/librustc_codegen_ssa/base.rs

+51-8
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
1515
1616
use crate::back::write::{
17-
start_async_codegen, submit_post_lto_module_to_llvm, submit_pre_lto_module_to_llvm,
18-
OngoingCodegen,
17+
start_async_codegen, submit_codegened_module_to_llvm, submit_post_lto_module_to_llvm,
18+
submit_pre_lto_module_to_llvm, OngoingCodegen,
1919
};
2020
use crate::common::{IntPredicate, RealPredicate, TypeKind};
2121
use crate::meth;
@@ -40,6 +40,7 @@ use rustc::ty::{self, Instance, Ty, TyCtxt};
4040
use rustc_codegen_utils::{check_for_rustc_errors_attr, symbol_names_test};
4141
use rustc_data_structures::fx::FxHashMap;
4242
use rustc_data_structures::profiling::print_time_passes_entry;
43+
use rustc_data_structures::sync::{par_iter, Lock, ParallelIterator};
4344
use rustc_hir as hir;
4445
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
4546
use rustc_index::vec::Idx;
@@ -606,20 +607,62 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
606607
codegen_units
607608
};
608609

609-
let mut total_codegen_time = Duration::new(0, 0);
610+
let total_codegen_time = Lock::new(Duration::new(0, 0));
610611

611-
for cgu in codegen_units.into_iter() {
612+
let cgu_reuse: Vec<_> = tcx.sess.time("find cgu reuse", || {
613+
codegen_units.iter().map(|cgu| determine_cgu_reuse(tcx, &cgu)).collect()
614+
});
615+
616+
let mut cgus: FxHashMap<usize, _> = if cfg!(parallel_compiler) {
617+
tcx.sess.time("compile first CGUs", || {
618+
// Try to find one CGU to compile per thread.
619+
let cgus: Vec<_> = cgu_reuse
620+
.iter()
621+
.enumerate()
622+
.filter(|&(_, reuse)| reuse == &CguReuse::No)
623+
.take(tcx.sess.threads())
624+
.collect();
625+
626+
// Compile the found CGUs in parallel.
627+
par_iter(cgus)
628+
.map(|(i, _)| {
629+
let start_time = Instant::now();
630+
let module = backend.compile_codegen_unit(tcx, codegen_units[i].name());
631+
let mut time = total_codegen_time.lock();
632+
*time += start_time.elapsed();
633+
(i, module)
634+
})
635+
.collect()
636+
})
637+
} else {
638+
FxHashMap::default()
639+
};
640+
641+
let mut total_codegen_time = total_codegen_time.into_inner();
642+
643+
for (i, cgu) in codegen_units.into_iter().enumerate() {
612644
ongoing_codegen.wait_for_signal_to_codegen_item();
613645
ongoing_codegen.check_for_errors(tcx.sess);
614646

615-
let cgu_reuse = determine_cgu_reuse(tcx, &cgu);
647+
let cgu_reuse = cgu_reuse[i];
616648
tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
617649

618650
match cgu_reuse {
619651
CguReuse::No => {
620-
let start_time = Instant::now();
621-
backend.compile_codegen_unit(tcx, cgu.name(), &ongoing_codegen.coordinator_send);
622-
total_codegen_time += start_time.elapsed();
652+
let (module, cost) = if let Some(cgu) = cgus.remove(&i) {
653+
cgu
654+
} else {
655+
let start_time = Instant::now();
656+
let module = backend.compile_codegen_unit(tcx, cgu.name());
657+
total_codegen_time += start_time.elapsed();
658+
module
659+
};
660+
submit_codegened_module_to_llvm(
661+
&backend,
662+
&ongoing_codegen.coordinator_send,
663+
module,
664+
cost,
665+
);
623666
false
624667
}
625668
CguReuse::PreLto => {

src/librustc_codegen_ssa/traits/backend.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::write::WriteBackendMethods;
22
use super::CodegenObject;
3+
use crate::ModuleCodegen;
34

45
use rustc::middle::cstore::EncodedMetadata;
56
use rustc::session::{config, Session};
@@ -10,7 +11,6 @@ use rustc_codegen_utils::codegen_backend::CodegenBackend;
1011
use rustc_span::symbol::Symbol;
1112
use syntax::expand::allocator::AllocatorKind;
1213

13-
use std::sync::mpsc;
1414
use std::sync::Arc;
1515

1616
pub trait BackendTypes {
@@ -34,7 +34,7 @@ impl<'tcx, T> Backend<'tcx> for T where
3434
{
3535
}
3636

37-
pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send {
37+
pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Send + Sync {
3838
fn new_metadata(&self, sess: TyCtxt<'_>, mod_name: &str) -> Self::Module;
3939
fn write_compressed_metadata<'tcx>(
4040
&self,
@@ -52,8 +52,7 @@ pub trait ExtraBackendMethods: CodegenBackend + WriteBackendMethods + Sized + Se
5252
&self,
5353
tcx: TyCtxt<'_>,
5454
cgu_name: Symbol,
55-
tx_to_llvm_workers: &mpsc::Sender<Box<dyn std::any::Any + Send>>,
56-
);
55+
) -> (ModuleCodegen<Self::Module>, u64);
5756
// If find_features is true this won't access `sess.crate_types` by assuming
5857
// that `is_pie_binary` is false. When we discover LLVM target features
5958
// `sess.crate_types` is uninitialized so we cannot access it.

0 commit comments

Comments
 (0)