Skip to content

Commit f9d60cf

Browse files
committed
Do asm compilation and object file emission in parallel
1 parent 1a0dfb3 commit f9d60cf

File tree

1 file changed

+56
-24
lines changed

1 file changed

+56
-24
lines changed

src/driver/aot.rs

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
use std::fs::File;
55
use std::path::PathBuf;
66
use std::sync::Arc;
7+
use std::thread::JoinHandle;
78

89
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
910
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
@@ -18,6 +19,7 @@ use rustc_session::Session;
1819

1920
use cranelift_object::{ObjectBuilder, ObjectModule};
2021

22+
use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken};
2123
use crate::global_asm::GlobalAsmConfig;
2224
use crate::{prelude::*, BackendConfig};
2325

@@ -27,18 +29,24 @@ struct ModuleCodegenResult {
2729
existing_work_product: Option<(WorkProductId, WorkProduct)>,
2830
}
2931

30-
impl<HCX> HashStable<HCX> for ModuleCodegenResult {
32+
enum OngoingModuleCodegen {
33+
Sync(Result<ModuleCodegenResult, String>),
34+
Async(JoinHandle<Result<ModuleCodegenResult, String>>),
35+
}
36+
37+
impl<HCX> HashStable<HCX> for OngoingModuleCodegen {
3138
fn hash_stable(&self, _: &mut HCX, _: &mut StableHasher) {
3239
// do nothing
3340
}
3441
}
3542

3643
pub(crate) struct OngoingCodegen {
37-
modules: Vec<Result<ModuleCodegenResult, String>>,
44+
modules: Vec<OngoingModuleCodegen>,
3845
allocator_module: Option<CompiledModule>,
3946
metadata_module: Option<CompiledModule>,
4047
metadata: EncodedMetadata,
4148
crate_info: CrateInfo,
49+
concurrency_limiter: ConcurrencyLimiter,
4250
}
4351

4452
impl OngoingCodegen {
@@ -50,7 +58,15 @@ impl OngoingCodegen {
5058
let mut work_products = FxHashMap::default();
5159
let mut modules = vec![];
5260

53-
for module_codegen_result in self.modules {
61+
for module_codegen in self.modules {
62+
let module_codegen_result = match module_codegen {
63+
OngoingModuleCodegen::Sync(module_codegen_result) => module_codegen_result,
64+
OngoingModuleCodegen::Async(join_handle) => match join_handle.join() {
65+
Ok(module_codegen_result) => module_codegen_result,
66+
Err(panic) => std::panic::resume_unwind(panic),
67+
},
68+
};
69+
5470
let module_codegen_result = match module_codegen_result {
5571
Ok(module_codegen_result) => module_codegen_result,
5672
Err(err) => sess.fatal(&err),
@@ -90,6 +106,8 @@ impl OngoingCodegen {
90106
}
91107
}
92108

109+
drop(self.concurrency_limiter);
110+
93111
(
94112
CodegenResults {
95113
modules,
@@ -233,12 +251,13 @@ fn reuse_workproduct_for_cgu(
233251

234252
fn module_codegen(
235253
tcx: TyCtxt<'_>,
236-
(backend_config, global_asm_config, cgu_name): (
254+
(backend_config, global_asm_config, cgu_name, token): (
237255
BackendConfig,
238256
Arc<GlobalAsmConfig>,
239257
rustc_span::Symbol,
258+
ConcurrencyLimiterToken,
240259
),
241-
) -> Result<ModuleCodegenResult, String> {
260+
) -> OngoingModuleCodegen {
242261
let cgu = tcx.codegen_unit(cgu_name);
243262
let mono_items = cgu.items_in_deterministic_order(tcx);
244263

@@ -280,23 +299,26 @@ fn module_codegen(
280299
cgu.is_primary(),
281300
);
282301

283-
let global_asm_object_file = crate::global_asm::compile_global_asm(
284-
&global_asm_config,
285-
cgu.name().as_str(),
286-
&cx.global_asm,
287-
)?;
288-
289-
tcx.sess.time("write object file", || {
290-
emit_cgu(
291-
&global_asm_config.output_filenames,
292-
&cx.profiler,
293-
cgu.name().as_str().to_string(),
294-
module,
295-
cx.debug_context,
296-
cx.unwind_context,
297-
global_asm_object_file,
298-
)
299-
})
302+
let cgu_name = cgu.name().as_str().to_owned();
303+
304+
OngoingModuleCodegen::Async(std::thread::spawn(move || {
305+
let global_asm_object_file =
306+
crate::global_asm::compile_global_asm(&global_asm_config, &cgu_name, &cx.global_asm)?;
307+
308+
let codegen_result = cx.profiler.verbose_generic_activity("write object file").run(|| {
309+
emit_cgu(
310+
&global_asm_config.output_filenames,
311+
&cx.profiler,
312+
cgu_name,
313+
module,
314+
cx.debug_context,
315+
cx.unwind_context,
316+
global_asm_object_file,
317+
)
318+
});
319+
std::mem::drop(token);
320+
codegen_result
321+
}))
300322
}
301323

302324
pub(crate) fn run_aot(
@@ -321,6 +343,8 @@ pub(crate) fn run_aot(
321343

322344
let global_asm_config = Arc::new(crate::global_asm::GlobalAsmConfig::new(tcx));
323345

346+
let mut concurrency_limiter = ConcurrencyLimiter::new(tcx.sess, cgus.len());
347+
324348
let modules = super::time(tcx, backend_config.display_cg_time, "codegen mono items", || {
325349
cgus.iter()
326350
.map(|cgu| {
@@ -338,13 +362,20 @@ pub(crate) fn run_aot(
338362
.with_task(
339363
dep_node,
340364
tcx,
341-
(backend_config.clone(), global_asm_config.clone(), cgu.name()),
365+
(
366+
backend_config.clone(),
367+
global_asm_config.clone(),
368+
cgu.name(),
369+
concurrency_limiter.acquire(),
370+
),
342371
module_codegen,
343372
Some(rustc_middle::dep_graph::hash_result),
344373
)
345374
.0
346375
}
347-
CguReuse::PreLto => reuse_workproduct_for_cgu(tcx, &*cgu),
376+
CguReuse::PreLto => {
377+
OngoingModuleCodegen::Sync(reuse_workproduct_for_cgu(tcx, &*cgu))
378+
}
348379
CguReuse::PostLto => unreachable!(),
349380
}
350381
})
@@ -424,6 +455,7 @@ pub(crate) fn run_aot(
424455
metadata_module,
425456
metadata,
426457
crate_info: CrateInfo::new(tcx, target_cpu),
458+
concurrency_limiter,
427459
})
428460
}
429461

0 commit comments

Comments
 (0)