1414//! int)` and `rec(x=int, y=int, z=int)` will have the same `llvm::Type`.
1515
1616use 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} ;
2020use crate :: common:: { IntPredicate , RealPredicate , TypeKind } ;
2121use crate :: meth;
@@ -40,6 +40,7 @@ use rustc::ty::{self, Instance, Ty, TyCtxt};
4040use rustc_codegen_utils:: { check_for_rustc_errors_attr, symbol_names_test} ;
4141use rustc_data_structures:: fx:: FxHashMap ;
4242use rustc_data_structures:: profiling:: print_time_passes_entry;
43+ use rustc_data_structures:: sync:: { par_iter, Lock , ParallelIterator } ;
4344use rustc_hir as hir;
4445use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
4546use 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 => {
0 commit comments