44use std:: fs:: File ;
55use std:: path:: PathBuf ;
66use std:: sync:: Arc ;
7+ use std:: thread:: JoinHandle ;
78
89use rustc_codegen_ssa:: back:: metadata:: create_compressed_metadata_file;
910use rustc_codegen_ssa:: { CodegenResults , CompiledModule , CrateInfo , ModuleKind } ;
@@ -18,6 +19,7 @@ use rustc_session::Session;
1819
1920use cranelift_object:: { ObjectBuilder , ObjectModule } ;
2021
22+ use crate :: concurrency_limiter:: { ConcurrencyLimiter , ConcurrencyLimiterToken } ;
2123use crate :: global_asm:: GlobalAsmConfig ;
2224use 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
3643pub ( 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
4452impl 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
234252fn 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
302324pub ( 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