4
4
use std:: fs:: File ;
5
5
use std:: path:: PathBuf ;
6
6
use std:: sync:: Arc ;
7
+ use std:: thread:: JoinHandle ;
7
8
8
9
use rustc_codegen_ssa:: back:: metadata:: create_compressed_metadata_file;
9
10
use rustc_codegen_ssa:: { CodegenResults , CompiledModule , CrateInfo , ModuleKind } ;
@@ -18,6 +19,7 @@ use rustc_session::Session;
18
19
19
20
use cranelift_object:: { ObjectBuilder , ObjectModule } ;
20
21
22
+ use crate :: concurrency_limiter:: { ConcurrencyLimiter , ConcurrencyLimiterToken } ;
21
23
use crate :: global_asm:: GlobalAsmConfig ;
22
24
use crate :: { prelude:: * , BackendConfig } ;
23
25
@@ -27,18 +29,24 @@ struct ModuleCodegenResult {
27
29
existing_work_product : Option < ( WorkProductId , WorkProduct ) > ,
28
30
}
29
31
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 {
31
38
fn hash_stable ( & self , _: & mut HCX , _: & mut StableHasher ) {
32
39
// do nothing
33
40
}
34
41
}
35
42
36
43
pub ( crate ) struct OngoingCodegen {
37
- modules : Vec < Result < ModuleCodegenResult , String > > ,
44
+ modules : Vec < OngoingModuleCodegen > ,
38
45
allocator_module : Option < CompiledModule > ,
39
46
metadata_module : Option < CompiledModule > ,
40
47
metadata : EncodedMetadata ,
41
48
crate_info : CrateInfo ,
49
+ concurrency_limiter : ConcurrencyLimiter ,
42
50
}
43
51
44
52
impl OngoingCodegen {
@@ -50,7 +58,15 @@ impl OngoingCodegen {
50
58
let mut work_products = FxHashMap :: default ( ) ;
51
59
let mut modules = vec ! [ ] ;
52
60
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
+
54
70
let module_codegen_result = match module_codegen_result {
55
71
Ok ( module_codegen_result) => module_codegen_result,
56
72
Err ( err) => sess. fatal ( & err) ,
@@ -90,6 +106,8 @@ impl OngoingCodegen {
90
106
}
91
107
}
92
108
109
+ drop ( self . concurrency_limiter ) ;
110
+
93
111
(
94
112
CodegenResults {
95
113
modules,
@@ -233,12 +251,13 @@ fn reuse_workproduct_for_cgu(
233
251
234
252
fn module_codegen (
235
253
tcx : TyCtxt < ' _ > ,
236
- ( backend_config, global_asm_config, cgu_name) : (
254
+ ( backend_config, global_asm_config, cgu_name, token ) : (
237
255
BackendConfig ,
238
256
Arc < GlobalAsmConfig > ,
239
257
rustc_span:: Symbol ,
258
+ ConcurrencyLimiterToken ,
240
259
) ,
241
- ) -> Result < ModuleCodegenResult , String > {
260
+ ) -> OngoingModuleCodegen {
242
261
let cgu = tcx. codegen_unit ( cgu_name) ;
243
262
let mono_items = cgu. items_in_deterministic_order ( tcx) ;
244
263
@@ -280,23 +299,26 @@ fn module_codegen(
280
299
cgu. is_primary ( ) ,
281
300
) ;
282
301
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
+ } ) )
300
322
}
301
323
302
324
pub ( crate ) fn run_aot (
@@ -321,6 +343,8 @@ pub(crate) fn run_aot(
321
343
322
344
let global_asm_config = Arc :: new ( crate :: global_asm:: GlobalAsmConfig :: new ( tcx) ) ;
323
345
346
+ let mut concurrency_limiter = ConcurrencyLimiter :: new ( tcx. sess , cgus. len ( ) ) ;
347
+
324
348
let modules = super :: time ( tcx, backend_config. display_cg_time , "codegen mono items" , || {
325
349
cgus. iter ( )
326
350
. map ( |cgu| {
@@ -338,13 +362,20 @@ pub(crate) fn run_aot(
338
362
. with_task (
339
363
dep_node,
340
364
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
+ ) ,
342
371
module_codegen,
343
372
Some ( rustc_middle:: dep_graph:: hash_result) ,
344
373
)
345
374
. 0
346
375
}
347
- CguReuse :: PreLto => reuse_workproduct_for_cgu ( tcx, & * cgu) ,
376
+ CguReuse :: PreLto => {
377
+ OngoingModuleCodegen :: Sync ( reuse_workproduct_for_cgu ( tcx, & * cgu) )
378
+ }
348
379
CguReuse :: PostLto => unreachable ! ( ) ,
349
380
}
350
381
} )
@@ -424,6 +455,7 @@ pub(crate) fn run_aot(
424
455
metadata_module,
425
456
metadata,
426
457
crate_info : CrateInfo :: new ( tcx, target_cpu) ,
458
+ concurrency_limiter,
427
459
} )
428
460
}
429
461
0 commit comments