14
14
//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
15
15
16
16
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 ,
19
19
} ;
20
20
use crate :: common:: { IntPredicate , RealPredicate , TypeKind } ;
21
21
use crate :: meth;
@@ -40,6 +40,7 @@ use rustc::ty::{self, Instance, Ty, TyCtxt};
40
40
use rustc_codegen_utils:: { check_for_rustc_errors_attr, symbol_names_test} ;
41
41
use rustc_data_structures:: fx:: FxHashMap ;
42
42
use rustc_data_structures:: profiling:: print_time_passes_entry;
43
+ use rustc_data_structures:: sync:: { par_iter, Lock , ParallelIterator } ;
43
44
use rustc_hir as hir;
44
45
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
45
46
use rustc_index:: vec:: Idx ;
@@ -606,20 +607,62 @@ pub fn codegen_crate<B: ExtraBackendMethods>(
606
607
codegen_units
607
608
} ;
608
609
609
- let mut total_codegen_time = Duration :: new ( 0 , 0 ) ;
610
+ let total_codegen_time = Lock :: new ( Duration :: new ( 0 , 0 ) ) ;
610
611
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 ( ) {
612
644
ongoing_codegen. wait_for_signal_to_codegen_item ( ) ;
613
645
ongoing_codegen. check_for_errors ( tcx. sess ) ;
614
646
615
- let cgu_reuse = determine_cgu_reuse ( tcx , & cgu ) ;
647
+ let cgu_reuse = cgu_reuse [ i ] ;
616
648
tcx. sess . cgu_reuse_tracker . set_actual_reuse ( & cgu. name ( ) . as_str ( ) , cgu_reuse) ;
617
649
618
650
match cgu_reuse {
619
651
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
+ ) ;
623
666
false
624
667
}
625
668
CguReuse :: PreLto => {
0 commit comments